准备工作
首先必须保证本地安装了nodejs
,因为webpack
是构建在其之上,请参考官网。下载最新的LTS
,也就是长期维护版,像安装其他软件一样,狂按下一步
即可,完成之后打开命令行
工具,也就是cmd
。
node -v
npm -v
复制代码
通过上面两条命令即可得到node
以及npm
的版本信息,注意:npm
是node
的包管理工具。
安装
在安装webpack
的时候一般有两种情况:全局
,本地工作目录
。二者的区别便是,通过全局安装的webpack可以在计算机任何目录
执行webpack命令,而后者只能在当前工作目录
执行。
在安装的时候我们通常会安装2个包:webpack
、webpack-cli
,前者是wepack主包,后者可以在命令行里面执行webpack命令。
全局安装
下面就开始全局
安装webpack
npm install webpack webpack-cli --global
复制代码
上面是完整的命令行代码,也可通过下面的简写
模式。
npm i -g webpack webpack-cli
复制代码
这里需要注意的是,在使用mac
的小伙伴,一定要记得在最前面加上sudo
。
sudo npm i -g webpack webpack-cli
复制代码
按照提示输入电脑的登陆密码
即可。
安装完成后,通过webpack -v
来查看下相关信息。
到这里,webpack
的全局
安装就完成了,但是在实际工作中还是不大推荐这种形式,这样会让你所有项目锁定一个webpack
版本,而且在运行不同webpack
版本项目会导致构建失败。
为了更加灵活且避免一些不必要的错误,在实际工作中还是推荐在当前工作目录下安装,这样就算换了一台电脑也不会出现问题。
本地工作目录安装
在开始之前,需要先创建一个工作目录,并且初始化一个node
的配置文件,也就是我们常见的package.json
。
npm init -y
复制代码
这样就会在项目根目录自动创建好package.json
文件。
接下来,就开始在当前目录执行如下命令:
npm install webpack webpack-cli --save-dev
//简写
npm i -D webpack webpack-cli
复制代码
到此,本地安装就完成了,我们就可以在当前目录下执行webpack
命令。
运行
为了方便我们测试简单的webpack
打包,我们先创建2个js
文件。
src/c1.js
在c1.js
中,我们通过export
默认导出一个add
函数。
export default function add (a, b) {
console.log(`a+b=${a + b}`);
}
复制代码
src/index.js
在index.js
中,我们通过import
引入c1.js
导出的add
函数,并进行一次调用。
import add from './c1.js'
add(3, 4)
复制代码
通过在当前目录下执行webpack
命令,这时候会自动创建一个dist
目录,里面包含一个main.js
,这就是webpack为我们打包出来的js代码。
仔细思考一下,我们貌似并没有配置什么,也就是单纯的安装了webpack
必须的两个依赖包,那到底webpack是依据什么来进行打包的?
webpack --stats detailed
复制代码
执行上述命令,我们就可以看到详细的webpack打包信息了。
思考:这时候在命令行执行的
webpack
命令是全局的还是当前目录下的呢?
为了测试这一结果,我们卸载掉全局的webpack
。
npm uninstall --global webpack webpack-cli
复制代码
然后,我们再次在工作目录下执行webpack
指令,我们会发现,webpack找不到了,这就说明,我们刚才执行的指令是全局指令。
如果我们没有全局的webpack
,是不是这个项目就没法构建了?不是的,这时候我们可以使用npx
来执行webpack
命令。
npx webpack
复制代码
这时候,我们又能正常进行打包了。
有小伙伴这时候可能就有疑问了,npx
到底是什么?居然有如此魔法,那他到底使用的是哪里的webpack
?
npx
是npm5.2
之后发布的一个命令,简单理解就是我们可以用npx来执行各种命令,npx会默认从当前目录去查找有没有webpack
,如果没有就会依次往上一层去寻找,而这时候我们当前目录正好有webpack
,所以,npx就会执行当前目录下的webpack
。
到这里,webpack的准备工作以及如何运行就介绍完了,但是我们还并不会去控制webpack
按照我们的需求来进行构建,例如,我要以哪个文件为入口,我要将打包文件放在哪里等等。接下来我们就逐步介绍webpack
的配置文件。
配置
webpack
默认提供了两种配置形式:终端命令
,配置文件
。
终端命令
webpack给我们提供了丰富的命令行指令,通过webpack --help
来查看。
接下来,我们小试牛刀,来看看常用的命令行指令。
例如:我们要指定入口为:src/index.js
,并且指定mode
为production
。
npx webpack --entry ./src/index.js --mode production
复制代码
这样,我们会看到再次生成dist/main.js
,如果我们想自定义目录以及生成的文件名呢,这时候我们需要配置其他参数,这样一来,我们的命令会变得非常长,这样肯定不是最好的方案,webpack
也给我们提供了另外一种配置方案,通过webpack.config.js
来配置这些打包信息。
配置文件
首先,在项目根目录创建webpack.config.js
文件(不可更改文件名),配置文件默认采用的是commonjs
语法,通过module.exports
导出一个配置对象,webpack会自动去读取该配置文件。
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist') //这里必须用path处理路径,否则报错。
},
mode: 'none' //指定开发模式,避免控制台报错。
}
复制代码
上面就是一个最基本的webpack
的配置文件,指定了入口,出口以及开发环境,当我们再次执行:npx webpack
,也会生成dist/bundle.js
。
难道webpack
就这点能耐?接下来我们开始了解webpack
的插件,这样可以简化我们的开发流程。
插件
我们可以把webpack
想象成一条生产线,入口文件我们就想象成原材料,中间会经过各种工序才能生产出我们需要的成品,而这中间有可能会用到各种工具来辅助,我们就可以把webpack的插件想象成这些工具。
下面我们来介绍几种工作中常用的插件。
HtmlWebpackPlugin
在实际工作中,我们肯定不仅仅是为了生成一个js
文件这么简单,我们还需要将生成的js文件自动引入html
中才算完美,不然每次还要手动去引入,稍不注意还会出错,这个插件就是为了解决我们这个问题。
首先,当然是安装插件:
npm i -D html-webpack-plugin
复制代码
安装完之后,我们当然要在webpack.config.js
中配置该插件。
...
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
...
plugins: [
new HtmlWebpackPlugin()
]
}
复制代码
再次执行:npx webpack
,这时候在dist
目录下不仅仅只有一个bundle.js
了,还有一个index.html
,并且已经自动引入我们生成的js文件,在浏览器中打开html
文件,js也是可以正常运行的。
我们打开生成的index.html
发现里面的代码都是插件给我们自动生成的,可恶的控制欲不能忍受不可控的代码,我们能让他按照我们提供的html格式生成文件吗?当然是可以的!
new HtmlWebpackPlugin({
template: 'index.html', //模板文件
filename: 'app.html', //生成的html文件名称
inject: 'body' //js插入的位置,默认在head。
})
复制代码
这样,我们就可以为所欲为了。
再次打开熟悉的dist
目录,除了之前的html文件,又给我们生成了新的app.html
,之前的html文件自然就没用了,总不能每次要我们手动去删除吧,当然不行,文件少还行,万一来个几十上百个无用文件,不说了,手抖。
清理dist
要在每次打包之前都清理掉之前的旧文件,只需要在output
中配置clean
属性即可。
output: {
...,
clean: true
}
复制代码
使用 source map
这时候,我们故意写个错误的语法,
修改src/index.js
...
cosole.log('hhh');
复制代码
将webpack.config.js
配置文件中的mode
改成development
,再次执行:npx webpack
,并且在浏览器打开dist/app.html
。
我们可以发现他并不能指向我们源码中的错误位置,这对我们开发调试来说简直太难了。
接着,我们修改webpack.config.js
,配置devtool
为:inline-source-map
,并再次执行打包,并刷新浏览器。
module.exports = {
...,
devtool: 'inline-source-map'
}
复制代码
这次就正确的指出了错误语法的位置了。
思考:不知小伙伴注意到没有,我们每需改一次都要手动执行
npx webpack
,这哪里是前端自动化,这跟工地搬砖有啥区别,那怎样可以一劳永逸,很简单,执行:npx webpack --watch
,给webpack加个监工不就是了,这样只要我们的项目有文件改变了,就会自动执行打包。
自动打包解决了,可每次我们还是要手动刷新一下浏览器才能看到最新的结果,这显然不是我们所期待的。
搭建开发环境
webpack-dev-server
就是用来解决我们上一个痛点,通过它可以在我们本地启动一个服务器,并且可以实现实时刷新。
安装 webpack-dev-server
npm i -D webpack-dev-server
复制代码
修改webpack.config.js
module.exports = {
...,
devServer: {
static: './dist'
}
}
复制代码
执行npx webpack-dev-server
,这时候就会自动启动一个server
。
在浏览器打开:http://localhost:8080
真相:
webpack-dev-server
并不需要dist
目录的文件,而是直接读取的内存,所以就算我们删掉dist
目录也依然能正常访问。
资源模块
webpack除了可以打包我们的js文件,还可以打包其他文件吗?例如:字体
,图片
等等,在这之前,我们通常用gulp
或者grunt
来处理我们的资源文件,将资源移动到dist
或者build
,其实webpack
最为出色的除了引入js还可以使用内置的资源模块(asset modules)来引入任何其他类型的资源。
资源模块类型分为如下4种:
asset/resource: 发送一个单独的文件并导出URI
asset/inline:导出资源的Data URI
asset/source:导出资源的源代码
asset:会在导出一个URI和发送一个单独的文件之间自动选择