loader
style-loader & css-loader
- 安装
npm i -D style-loader css-loader
- 配置
// webpack.config.js module.exports = { // ...省略其他配置 module:{ rules:[ { test:/\.css$/, use:['style-loader','css-loader'] // 从右向左解析原则 } ] } }
less-loader
- 安装
npm i -D less less-loader
- 配置
module.exports = { // ...省略其它配置 module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader', 'less-loader'] // 从右向左解析原则 } ] } }
postcss-loader
为css添加浏览器前缀
- 安装
npm i -D postcss-loader autoprefixer
- 配置
接下来还需要引入// webpack.config.js module.exports = { module:{ rules:[ test/\.less$/, use:['style-loader','css-loader','postcss-loader','less-loader'] // 从右向左解析原则 ] } }
autoprefixer
使配置生效,有两种方式
- 在项目根目录下创建一个
postcss.config.js
文件,配置如下:module.exports = { plugins: [require('autoprefixer')] // 引用该插件即可 } ```
- 直接在
webpack.config.js
文件里配置// webpack.config.js module.exports = { // ...省略其它配置 module: { rules: [{ test: /\.less$/, use: ['style-loader', 'css-loader', { loader: 'postcss-loader', options: { plugins: [require('autoprefixer')] }, }, 'less-loader'] // 从右向左解析原则 }] } } ```
file-loader & url-loader
file-loader
就是将文件在进行一些处理后(主要是处理文件名和路径、解析文件url),并将文件移动到输出的目录中。
url-loader
一般与file-loader
搭配使用,功能与file-loader
类似,如果文件小于限制的大小,则会返回base64编码,否则使用file-loader
将文件移动到输出的目录中
- 安装
npm i -D file-loader url-loader
- 配置
// webpack.config.js module.exports = { module: { rules: [ // ... { test: /\.(jpe?g|png|gif|)$/i, // 图片文件 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: file-loader, options: { name: 'img/[name].[hash:8].[ext]' } } } } ] }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, // 媒体文件 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: 'file-loader', options: { name: 'media/[name].[hash:8].[ext]' } } } } ] }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i, // 字体 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: 'file-loader', options: { name: 'fonts/[name].[hash:8].[ext]' } } } } ] } ] } }
babel-loader & @babel/preset-env & @babel/core
- 安装
npm i babel-loader @babel/preset-env @babel/core
babel-loader
与babel-core
的对应关系babel-loader babel-core 8.x 7.x 7.x 6.x - 配置
// webpack.config.js module.exports = { // ...省略其它配置 module: { rules: [ test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } }, exclude: /node-modules/ ] } }
babel-polyfill
babel-polyfill
并不属于loader。babel-loader
会将ES6/7/8的语法转换成ES5的语法,但是对于新的api并不会转换,例如Promise
、Generator
、Set
、Maps
、Proxy
等,此时,便可以借助babel-polyfill
来解决。
- 安装
npm i @babel/polyfill
- 配置
有三种方式可供使用import
方式使用import '@babel/polyfill' // 在入口文件最上方使用import引入
require
方式使用require('@babel/polyfill') // 在入口文件最上方使用require引入
webpack
配置入口文件// webpack.config.js module.exports = { entry: ['@babel/polyfill', './app/.js'] }
plugin
html-webpack-plugin
- 安装
npm i -D html-webpack-plugin
- 配置
新建一个build同级的文件夹public,里面新建一个index.html文件。这个html文件就是webpack用的模板文件// webpack.config.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode:'development', // 开发模式 entry: path.resolve(__dirname,'../src/main.js'), // 入口文件 output: { filename: '[name].[hash:8].js', // 打包后的文件名称 path: path.resolve(__dirname,'../dist') // 打包后的目录 }, plugins:[ new HtmlWebpackPlugin({ template:path.resolve(__dirname,'../public/index.html') }) ] }
- 多文件开发配置
主要原理是创建多个html-webpack-plugin实例
这是一个vue-cli项目配置多文件的博客const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode:'development', // 开发模式 entry: { main:path.resolve(__dirname,'../src/main.js'), header:path.resolve(__dirname,'../src/header.js') }, output: { filename: '[name].[hash:8].js', // 打包后的文件名称 path: path.resolve(__dirname,'../dist') // 打包后的目录 }, plugins:[ new HtmlWebpackPlugin({ template:path.resolve(__dirname,'../public/index.html'), filename:'index.html', chunks:['main'] // 与入口文件对应的模块名 }), new HtmlWebpackPlugin({ template:path.resolve(__dirname,'../public/header.html'), filename:'header.html', chunks:['header'] // 与入口文件对应的模块名 }), ] }
clean-webpack-plugin
这个插件可以在每次打包输出前清空文件夹
- 安装
npm i -D clean-webpack-plugin
- 配置
const {CleanWebpackPlugin} = require('clean-webpack-plugin') module.exports = { // ...省略其他配置 plugins:[new CleanWebpackPlugin()] }
mini-css-extract-plugin
当我们使用了一系列的css相关loader来处理css后,会发现项目中的css都通过style标签的方式添加到了html文件中,但是当样式文件过多的时候,会显得混乱,所以需要将css拆分成外链的形式
webpack 4.0以前,使用extract-text-webpack-plugin
插件,把css样式从js文件中提取到单独的css文件中。webpack 4.0以后,官方推荐使用mini-extract-webpack-plugin
插件来打包文件
- 安装
npm i -D mini-extract-webpack-plugin
- 配置
// webpack.config.js const MiniExtractWebpackPlugin = require('mini-extract-webpack-plugin'); module.exports = { // ...省略其它配置 module: { rules: [ { test: /\.less$/, use: [MiniExtractWebpackPlugin.loader, 'css-loader', 'less-loader'] } ] }, plugins: [ new MiniExtractWebpackPlugin({ filename: '[name].[hash].css', chunkFileName: '[id].css' }) ] }
extract-text-webpack-plugin
mini-extract-webpack-plugin
插件暂时只能做到将所有css样式合并为一个css文件。所以,如果想拆分为一一对应的多个css文件,需要使用extract-text-webpack-plugin
插件
- 安装
npm i -D extract-text-webpack-plugin
- 配置
// webpack.config.js const path = require('path'); const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'); let indexLess = new ExtractTextWebpackPlugin('index.less'); let indexCss = new ExtractTextWebpackPlugin('index.css'); module.exports = { module: { rules: [ { test: /\.css$/, use: indexCss.extract({ use: ['css-loader'] }) }, { test: /\.less$/, use: indeLess.extract({ use: ['css-loader', 'less-loader'] }) } ] }, plugins: [ indexLess, cssLess ] }
webpack.HotModuleReplacementPlugin
搭配webpack的Server
服务配置开发环境热更新
- 安装(
webpack-dev-server
)npm i -D webpack-dev-server
- 配置
// webpack.config.js const webpack = require('webpack') module.exports = { // ...其它配置 devServer: { port: 3000, hot: true, contentBase: '../dist' }, plugins: [ new webpack.HotModuleReplacementPlugin() ] }
copy-webpack-plugin
此插件用来拷贝静态资源,通常用在生产环境
- 安装
npm i -D copy-webpack-plugin
- 配置
// webpack.prod.js const path = require('path') const copyWebpackPlugin = require('copy-webpack-plugin') module.exports = { // ...其它配置 plugins: [new copyWebpackPlugin([{ from: path.resolve(__dirname, '../public'), to: path.resolve(__dirname, '../dist') }])] }
optimizi-css-assets-webpack-plugin
对项目css资源进行压缩
- 安装
npm i -D optimize-css-assets-webpack-plugin
- 配置
// webpack.prod.js const optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') module.exports = { // ... 其它配置 optimization: { minimizer: [ new optimizeCssAssetsWebpackPlugin() ] } }
uglifyjs-webpack-plugin
当设置webpack
的环境为生产环境时,会自动压缩js代码,原则上并不需要引入uglifyjs-webpack-plugin
进行重复工作。但是optimize-css-assets-webpack-plugin
压缩css的同时会破坏原有的js压缩,所以,需要引入此插件对js进行压缩
- 安装
npm i -D uglifyjs-webpack-plugin
- 配置
// webpack.prod.js const uglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin') module.exports = { // ...其它配置 optimization: { minimizer: [ new uglifyjsWebpackPlugin({ cache: true, parallel: true, sourceMap: true }) ] } }
optimization.minimizer
允许通过提供一个或多个定制过的工具,覆盖默认压缩工具
happypack
在webpack构建过程中,实际上耗费时间大多数用在loader解析转换以及代码压缩中,日常开发中我们需要使用loader对jss、css、图片、字体等文件做转换操作,并且转换的文件数据量也是非常大。由于js单线程的特性使得这些转换操作不能并发处理文件,而是需要一个个文件进行处理。HappyPack的基本原理是将这部分任务分解到各个子进程中去并行处理,子进程处理完成后把结果发送到主进程中,从而减少总的构建时间。
- 安装
npm i -D happypack
- 配置
const HappPack = require('happypack') const os = require('os') const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }) module.exports = { // ...其他配置 module: { rules: [ { test: /\.js$/, use: [{ loader: 'happypack/loader?id=happyBabel' }], exclude: /node_modules/ } ], plugins: [ new HappyPack({ id: 'happyBabel', loaders: [ { loader: 'babel-loader', options: { preset: [['@babel/preset-env']], cacheDirectory: true } } ], threadPool: happyThreadPool }) ] } }
webpack-parallel-uglify-plugin
优化代码压缩时间。通过happypack
已经对loader转换做了优化,然后用此插件优化压缩时间
- 安装
npm i -D webpack-parallel-uglify-plugin
- 配置
const parallelUglifyPlugin = require('webpack-parallel-uglify-plugin') module.exports = { // ...省略其它配置 optimization: { minimizer: [ new parallelUglifyPlugin({ cacheDir: '.cache/', uglifyJs: { output: { comments: false, beautify: false }, compress: { drop_console: true, collapse_vars: true, reduce_vars: true } } }) ] } }
DllPlugin & DllreferencePlugin
抽离第三方模块,对于开发项目中不经常变更的静态依赖文件。类似于element-ui
、Vue
全家桶等。因为会很少变更,所以我们不希望这些依赖要被集成到每一次的构建中去。这样做的好处是每次更改本地代码文件的时候,webpack
只需要打包我项目本身的文件代码,而不会再去编译第三方库。以后只要不升级第三方包的时候,那么webpack
就不会对这些库去打包,这样可以快速的提高打包的速度。
-
配置
在与webpack
同级目录下新建webpack.dll.config.js
// webpack.dll.config.js const path = require('path') const webpack = require('webpack') module.exports = { // 想要打包的模块的数组 entry: { vendor: ['vue', 'element-ui'] }, output: { path: path.resolve(__dirname, 'static/js'), // 打包后文件输出的位置 filename: '[name].dll.js', library: '[name]_library' // 这里需要和webpack.Dllplugin中的name: [name]_library保持一致 }, plugins: [ new webpack.DllPlugin({ path: path.resolve({__dirname, '[name].mainfest.json'}), name: '[name]_library', context: __dirname }) ] }
在
package.json
中配置命令"dll": "webpack --config build/webpack.dll.config.js"
在
webpack.config.js
中配置module.exports = { plugins: [ new webpack.DllReferencePlugin({ context: __dirname, mainfest: require('./vendor-mainfest.json') }), new CopyWebpackPlugin({ from: 'static', to: 'static' }) ] }
当执行
npm run dll
命令的时候就会发现生成了verdor.dll.js
,然后我们只需要在html中手动引入这个js文件,之后每次打包就会跳过这些第三方依赖包,速度有明显提升。