参考文档:
核心概念
- 入口(entry)
- 出口(output)
- loader
- 插件(plugins)
1.入口(entry)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
每个依赖项随即被处理,最后输出到称之为 bundles 的文件中.
webpack.config.js
分离 应用程序(app) 和 第三方库(vendor) 入口
entry:{ app: './src/main.js' vendor: './src/vendors.js' }
main.js
2. 出口(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist
。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。
output: { path: config.build.assetsRoot, filename: '[name].js' //[name]是模块名 }
用[name]来赋予每个 bundle 一个唯一的名称,还有其它方法:
使用内部 chunk id
filename: "[id].bundle.js"
使用每次构建过程中,唯一的 hash 生成
filename: "[name].[hash].bundle.js"
使用基于每个 chunk 内容的 hash:
filename: "[chunkhash].bundle.js"
3. loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,
在 webpack 的配置中 loader 有两个目标:
test
属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。use
属性,表示进行转换时,应该使用哪个 loader。options
属性为字符串或对象。值可以传递到 loader 中,将其理解为 loader 选项
webpack.config.js
以上配置中,对一个单独的 module 对象定义了 rules
属性,里面包含两个必须属性:test
和 use
。这告诉 webpack 编译器(compiler) 如下信息:
“ 当你碰到「在
require()
/import
语句中被解析为 '.vue' 的路径」时,在你对它打包之前,先使用 vue-loader
转换一下。”
- 条件匹配:通过 test 、 include 、 exclude 三个配置项来命中 Loader 要应用规则的文件。
- 应用规则:对选中后的文件通过
use
配置项来应用 Loader,可以只应用一个 Loader 或者按照从右向左的顺序应用一组 Loader,同时还可以分别给 Loader 传入参数。
module: { rules: [ { // 命中 JavaScript 文件 test: /.js$/, // 用 babel-loader 转换 JavaScript 文件 // ?cacheDirectory 表示传给 babel-loader 的参数,用于缓存 babel 编译结果加快重新编译速度 use: ['babel-loader?cacheDirectory'], // 只命中src目录里的js文件,加快 Webpack 搜索速度 include: path.resolve(__dirname, 'src') }, { // 命中 SCSS 文件 test: /.scss$/, // 使用一组 Loader 去处理 SCSS 文件。 // 处理顺序为从后到前,即先交给 sass-loader 处理,再把结果交给 css-loader 最后再给 style-loader。 use: ['style-loader', 'css-loader', 'sass-loader'], // 排除 node_modules 目录下的文件 exclude: path.resolve(__dirname, 'node_modules'), } ] }
在 Loader 需要传入很多参数时,你还可以通过一个 Object 来描述,例如在上面的 babel-loader 配置中有如下代码:
use: [ { loader:'babel-loader', options:{ cacheDirectory:true, },// 省略其它 Loader ]
source Map
如果你想在浏览器中找到CSS样式的来源,可以在option中设置sourceMap : true
use:[ { loader:'css-loader', option:{ sourceMap: true } } ]
效果:
postcss-loader处理css
其中 autoprefixer 插件为CSS3添加解决浏览器兼容性的前缀
{ test: /.css$/, use: [ 'style-loader', 'css-loader', { loader: 'postcss-loader', options: { ident: 'postcss', plugins: [ require('autoprefixer')({...options}), ..., ] } } ] }
url-loader
根据图片大小,将图片优化base64编码
base64图片工具介绍:
1.支持 PNG、GIF、JPG、BMP、ICO 格式。
2.将图片转换为Base64编码,可以让你很方便地在没有上传文件的条件下将图片插入其它的网页、编辑器中。 这对于一些小的图片是极为方便的,因为你不需要再去寻找一个保存图片的地方。
3.假定生成的代码为"data:image/jpeg;base64, .....",那么你只需要全部复制,然后在插入图片的时候,地址填写这段代码即可。
4.CSS中使用:background-image: url("data:image/png;base64,iVBORw0KGgo=...");
5.HTML中使用:<img src="data:image/png;base64,iVBORw0KGgo=..." />
6.图片转换Base64,无线开发、HTML5、CSS3必备的工具,CSS DataURI Base64 工具。
7.将图片转换成base64编码的,在web网上一般用于小图片上,不仅可以减少图片的请求数量(集合到js、css代码中),还可以防止因为一些相对路径等问题导致图片404错误。
{ test: /.(png|jpe?g|gif|svg)(?.*)?$/, loader: 'url-loader', options: { limit: 10000, //目标文件的小于10kb时,转为base64 name: utils.assetsPath('img/[name].[hash:7].[ext]') } },
4. 插件(plugins)
插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
想要使用一个插件,你只需要 require()
它,然后把它添加到 plugins
数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new
操作符来创建它的一个实例。
MiniCssExtractPlugin
- 此插件将CSS提取到单独的文件中。它为每个包含CSS的JS文件创建一个CSS文件。它支持CSS和SourceMaps的按需加载。
- 这个插件只能在
production
style-loader
加载链的构建中使用.
安装插件:
npm install --save-dev mini-css-extract-plugin
配置:
webpack.config.js //引入插件 const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { //定义插件 plugins: [ new MiniCssExtractPlugin({ filename: '[name].css', //输出文件名 chunkFilename: '[id].css', }), ], module: { rules: [ { test: /.css$/, use: [ //使用插件 MiniCssExtractPlugin.loader, 'css-loader', ], }, ], }, };
HtmlWebpackPlugin
这是一个webpack插件,可以简化HTML文件的创建,为您的webpack
捆绑服务提供服务。这对于webpack
在文件名中包含哈希的包很有用,每次编译这些哈希值都会更改。
CleanWebpackPlugin
用于删除/清除构建文件夹的webpack插件。
5. 模式 mode
通过选择 development
或 production
之中的一个,来设置 mode
参数,你可以启用相应模式下的 webpack 内置的优化
module.exports = { mode: 'production' };
6. devtool
此选项控制是否以及如何生成源映射。
Instead of using the
devtool
option you can also useSourceMapDevToolPlugin
/EvalSourceMapDevToolPlugin
directly as it has more options. Never use both thedevtool
option and plugin together. Thedevtool
option adds the plugin internally so you would end up with the plugin applied twice.
生成和开发模式下使用的devtool不同,详情参阅 https://webpack.js.org/configuration/devtool/#root
分离开发(development)生产(production)
开发和生产构建的目标差别很大。在开发中,我们需要强大的源映射和本地主机服务器,具有实时重新加载或热模块替换。在生产中,我们的目标转向关注缩小的束,更轻的源图和优化的资产,以改善加载时间。通过这种逻辑分离,我们通常建议为每个环境编写单独的webpack配置。
通过使用webpack-merge将这些配置合并在一起
7. devServer 和热更新
devServer: { clientLogLevel: 'warning', // 可能的值有 none, error, warning 或者 info(默认值) hot: true, // 启用 webpack 的模块热替换特性, 这个需要配合: webpack.HotModuleReplacementPlugin插件 contentBase: path.join(__dirname, "dist"), // 告诉服务器从哪里提供内容, 默认情况下,将使用当前工作目录作为提供内容的目录 compress: true, // 一切服务都启用gzip 压缩 host: '0.0.0.0', // 指定使用一个 host。默认是 localhost。如果你希望服务器外部可访问 0.0.0.0 port: 8080, // 端口 open: true, // 是否打开浏览器 overlay: { // 出现错误或者警告的时候,是否覆盖页面线上错误消息。 warnings: true, errors: true }, publicPath: '/', // 此路径下的打包文件可在浏览器中访问。 proxy: { // 设置代理 "/api": { // 访问api开头的请求,会跳转到 下面的target配置 target: "http://192.168.0.102:8080", pathRewrite: {"^/api" : "/mockjsdata/5/api"} } }, quiet: true, // necessary for FriendlyErrorsPlugin. 启用 quiet 后,除了初始启动信息之外的任何内容都不会被打印到控制台。这也意味着来自 webpack 的错误或警告在控制台不可见。 watchOptions: { // 监视文件相关的控制选项 poll: true, // webpack 使用文件系统(file system)获取文件改动的通知。在某些情况下,不会正常工作。例如,当使用 Network File System (NFS) 时。Vagrant 也有很多问题。在这些情况下,请使用轮询. poll: true。当然 poll也可以设置成毫秒数,比如: poll: 1000 ignored: /node_modules/, // 忽略监控的文件夹,正则 aggregateTimeout: 300 // 默认值,当第一个文件更改,会在重新构建前增加延迟 } }
若要实现热更新,还需引入插件:
plugins:{ new webpack.NamedModulesPlugin(), // 更容易查看(patch)的依赖 new webpack.HotModuleReplacementPlugin() // 替换插件 }
8. eslint校验
module.exports = { // ... module: { rules: [ { test: /.js$/, exclude: /node_modules/, loader: "eslint-loader", options: { // eslint options (if necessary) } } ] } // ... };
module.exports = { // ... module: { rules: [ { test: /.js$/, exclude: /node_modules/, use: ["babel-loader", "eslint-loader"] } ] } // ... };
module.exports = { // ... module: { rules: [ { enforce: "pre", test: /.js$/, exclude: /node_modules/, loader: "eslint-loader" }, { test: /.js$/, exclude: /node_modules/, loader: "babel-loader" } ] } // ... };
项目目录
配置
在webpack.common.js
,我们现在有我们的设置entry
和output
配置,我们已经包含所需要的两种环境的任何插件。在webpack.dev.js和webpack.prod.js中,分别
设置mode
为development和production,并引入
const merge = require('webpack-merge'); const common = require('./webpack.common.js');
module.exports = merge(common,{
,
mode:'xxx'
});
以轻松地在dev
和中包含我们的常见配置prod。
npm脚本
在scripts中
重新配置我们的新配置。我们将使用开发一个为我们webpack-dev-server
,npm start
,脚本和生产一个为我们的npm run build
脚本:
package.json