1、为什么使用webpack
webpack通俗来说其实是一个代码打包机,正式一点叫JavaScript 应用程序的静态模块打包器(module bundler)。将具有依赖性的模块转换打包为我们所需要的静态资源。
其中包括
- 代码优化:将ES6转换为ES3,Less、Sass转换为Css,Css兼容等。
- 文件优化:文件压缩,文件合并等。
- 代码分割:模块化开发中的多页面抽离。
- 模块合并:单个页面中多模块的应用。
- 自动刷新:webpack可为开发者启用本地服务,使用Diff算法,进行热加载自动更新。
- 代码校验:使用第三方包等实现代码规范校验,如eslint。
- 自动发布:将我们写好的代码进行打包发布到服务器。
2、初始化项目
npm init -y
-yes/-y
的意思是直接略过所有问答,全部采用默认答案。
结果会生成最初的package.json文件。
{
"name": "webpackCabin",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
3、本地安装webpack(非全局)
首先确保安装node.js,登陆官网下载安装nodejs。
本地安装Webpack,不推荐全局安装,以便于在引入破坏式变更(breaking change)的依赖时,更容易分别升级项目:加上-dev/-d意味着这是开发依赖,上线的时候并不需要这个包。如果使用 webpack 4+ 版本,还需要安装 CLI。
npm i -D webpack webpack-cli
查看当前webpack版本
npm webpack -v // 6.4.1
4、开始之前需要谢学习的四个核心概念
- 入口(entry),指示 webpack 应该使用哪个模块,默认值为 ./src。
- 输出(output),
output.path
告诉 webpack 在哪里输出它所创建的 bundles,以及output.filename
如何命名这些文件,默认值为 ./dist。 - loader,让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript),如sass,less,png···使用test 属性标识出应该被对应的 loader 进行转换的某个或某些文件,使用use 属性,表示进行转换时,应该使用哪个 loader。特别注意在 webpack 配置中定义 loader 时,要定义在 module.rules 中,而不是 rules。
- 插件(plugins),loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。
当然还有模式的选择:通过选择 development 或 production 之中的一个,来设置 mode 参数,可以启用相应模式下的 webpack 内置优化。production 模式会把代码全部压缩而development 不会,在dev阶段我们可以清晰的看到文件打包的情况
./webpack.config.js
module.exports = {
mode: 'production'
};
5、webpack默认配置文件及修改
为什么webpack的配置文件默认为webpack.config.js
,不可以是其他的名称?
使用npx webpack
将会调用node_modules\.bin\webpack.cmd
@IF EXIST "%~dp0\node.exe" (
// 当前目录如果有node.exe则使用当前目录下的node执行"%~dp0\..\webpack\bin\webpack.js"
"%~dp0\node.exe" "%~dp0\..\webpack\bin\webpack.js" %*
) ELSE (
// 如果当前目录没有node.exe,则使用全局的node执行"%~dp0\..\webpack\bin\webpack.js"
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\webpack\bin\webpack.js" %*
)
代码结束会执行我们的webpack,node_modules\webpack\bin\webpack.js
,这个文件会去检查我们是否安装了webpack-cli
。
如果已经安装了,则会执行node_modules\webpack-cli\package.json
。
然后去找到node_modules\webpack-cli\bin\config\config-yargs.js
从而解析webpack.config.js。
在config-yargs.js
中有说明defaultDescription: "webpack.config.js or webpackfile.js"
。
这里也可以设置其他的配置文件名以及配置文件路径。
比如我webpack.config.js
将改为webpackConfig.js
,然后在package.json
中设置script参数.
{
···
"scripts": {
"start": "webpack --config webpackConfig.js"
},
···
}
运行脚本or npm run start
或者 npm start
等同于(注:不太通用的命令项则只能通过npm run <命令项>的形式执行)
> webpackCabin@1.0.0 start D:\Projects\webpackCabin
> webpack --config webpackConfig.js
webpack依旧能够找到我的配置文件webpackConfig.js
。
因为webpack是node编写的,所以webpack.config.js
内部是node的写法。
6、开始配置
新建打包目录
开发者自定义打包目录,通常将开发文件夹命名为/src。
手动配置webpack.config.js文件
-
首先来创建一个简单的配置对象
module.exports = { mode: 'development', entry: "./src/index.js", output: { filename: 'bundle.[hash:8].js', path: path.resolve('D:/Projects/webpackCabin/build') } }
mode:默认为production模式,生产出的代码已经被压缩。
entry:指定了打包文件的入口。
output:指定打包完成的代码文件的路径和名称。 -
使用path模块来进行优化output.path
特别注意的是output.path
必须使用绝对路径,但是如果我们的项目文件比较复杂,直接写绝对路径代码也不美观,这时我们可以通过nodejs的path模块来进行优化。let path = require('path'); module.exports = { mode: 'development', entry: "./src/index.js", output: { filename: 'bundle.[hash:8].js', path: path.resolve(path.resolve(__dirname, 'build')), //'D:/Projects/webpackCabin/build' } }
-
使用webpack-dev-server开启服务
安装npm i -s-d webpack-dev-server
添加脚本"dev": "webpack-dev-server --config webpackConfig.js"
运行npm run dev
这时可以在浏览器中访问http://localhost:8080/
,但此时进入的是我们的项目根目录,而我们的页面在build文件夹中。
配置webpackConfig.js的开发服务器的服务路径。··· module.exports = { devServer: { port: 3000, // 端口号 progress: true, //进度条 contentBase: './build', // 服务路径 }, ··· }
-
使用HtmlWebpackPlugin抽离页面
安装npm i -s-d html-webpack-plugin
在配置对象中添加plugins数组let path = require('path'); let HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { ··· plugins: [// 数组,存放所有的webpack插件 new HtmlWebpackPlugin({ // html文件抽离实例 template: './src/index.html', // 模板来源 filename: 'index.html', // 抽离生成的页面名称 minify: { // 页面压缩配置 removeAttributeQuotes: true, //删除属性引号 collapseWhitespace: true, //折叠空行 }, hash: true//为文件添加hash戳,不能在filename里添加,否则会找不到。 }) ] }
-
配置样式处理器
配置loader,以处理js以外的其他文件。
index.js中导入样式文件。import './style.css'
webpackConfig.js
··· module.exports = { ··· module: { // 模块 rules: [{// 规则数组 test: /\.css$/, use: [[{ loader: 'style-loader',// 默认情况下,style-loader 将 <style> 元素附加到页面<head> 标签的末尾 options: { // 当写成对象时,可以进行参数配置使 <style> 元素附加到页面<head> 标签的头部 insert: 'head', //style插入head的方式 } },'css-loader'], // css-loader负责接续@import这种语法, //'style-loader'负责把css插入head标签中, //loader数组从右向左执行 }] }, ··· }