webpack.config.js从0到1

1.铁皮段位

  1. // webpack.config.js
  2. const path = require('path');
  3. module.exports = {
  4. mode:'development', // 开发模式
  5. entry: path.resolve(__dirname,'../src/main.js'), // 入口文件
  6. output: {
  7. filename: 'output.js', // 打包后的文件名称
  8. path: path.resolve(__dirname,'../dist') // 打包后的目录
  9. }
  10. }

执行命令

webpack —config build/webpack.config.js

filename的哈希大法

filename:’[name]’.[hash:8].js

第一个插件配置,html-webpack-plugin
  1. plugins:[
  2. new HtmlWebpackPlugin({
  3. template:path.resolve(__dirname,'../public/index.html')
  4. })
  5. ]

多入口配置
  1. entry: {
  2. main:path.resolve(__dirname,'../src/main.js'),
  3. header:path.resolve(__dirname,'../src/header.js')
  4. },
  5. plugins:[
  6. new HtmlWebpackPlugin({
  7. template:path.resolve(__dirname,'../public/index.html'),
  8. filename:'index.html',
  9. chunks:['main'] // 与入口文件对应的模块名
  10. }),
  11. new HtmlWebpackPlugin({
  12. template:path.resolve(__dirname,'../public/header.html'),
  13. filename:'header.html',
  14. chunks:['header'] // 与入口文件对应的模块名
  15. }),
  16. ]

清除之前残留文件 clean-webpack-plugin
  1. const {CleanWebpackPlugin} = require('clean-webpack-plugin')
  2. plugins:[new CleanWebpackPlugin()]

引入css style-loader css-loader
  1. module:{
  2. rules: [
  3. {
  4. test:/\.css$/,
  5. use:['style-loader','css-loader'] // 从右向左解析原则
  6. }
  7. ]
  8. }

解析less less less-loader
  1. {
  2. test:/\.less$/,
  3. use:['style-loader','css-loader','less-loader'] // 从右向左解析原则
  4. }

解析sass sass sass-loader
  1. {
  2. test:/\.scss$/,
  3. use:['style-loader','css-loader','sass-loader'] // 从右向左解析原则
  4. }

为css添加浏览器前缀 postcss-loader autoprefixer

postcss生效的两种方式

1,在项目根目录下创建一个postcss.config.js文件,配置如下:

  1. module.exports = {
  2. plugins: [require('autoprefixer')] // 引用该插件即可了
  3. }

2、在webpack.config.js中配置

  1. // webpack.config.js
  2. module.exports = {
  3. //...省略其他配置
  4. module:{
  5. rules:[{
  6. test:/\.less$/,
  7. use:['style-loader','css-loader',{
  8. loader:'postcss-loader',
  9. options:{
  10. plugins:[require('autoprefixer')]
  11. }
  12. },'less-loader'] // 从右向左解析原则
  13. }]
  14. }
  15. }

拆分css mini-css-extract-plugin
  1. const MiniCssExtractPlugin = require("mini-css-extract-plugin");
  2. module.exports = {
  3. //...省略其他配置
  4. module: {
  5. rules: [
  6. //这一块要在后面新增,而不是覆盖以上配置
  7. {
  8. test: /\.sass$/,
  9. use: [
  10. MiniCssExtractPlugin.loader,
  11. 'css-loader',
  12. 'sass-loader'
  13. ],
  14. }
  15. //
  16. ]
  17. },
  18. plugins: [
  19. new MiniCssExtractPlugin({
  20. filename: "[name].[hash].css",
  21. chunkFilename: "[id].css",
  22. })
  23. ]
  24. }

拆分css extract-text-webpack-plugin@next

打包图片,字体,媒体等 file-loader url-loader
  1. // webpack.config.js
  2. module.exports = {
  3. // 省略其它配置 ...
  4. module: {
  5. rules: [
  6. // ...
  7. {
  8. test: /\.(jpe?g|png|gif)$/i, //图片文件
  9. use: [
  10. {
  11. loader: 'url-loader',
  12. options: {
  13. limit: 10240,
  14. fallback: {
  15. loader: 'file-loader',
  16. options: {
  17. name: 'img/[name].[hash:8].[ext]'
  18. }
  19. }
  20. }
  21. }
  22. ]
  23. },
  24. {
  25. test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, //媒体文件
  26. use: [
  27. {
  28. loader: 'url-loader',
  29. options: {
  30. limit: 10240,
  31. fallback: {
  32. loader: 'file-loader',
  33. options: {
  34. name: 'media/[name].[hash:8].[ext]'
  35. }
  36. }
  37. }
  38. }
  39. ]
  40. },
  41. {
  42. test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i, // 字体
  43. use: [
  44. {
  45. loader: 'url-loader',
  46. options: {
  47. limit: 10240,
  48. fallback: {
  49. loader: 'file-loader',
  50. options: {
  51. name: 'fonts/[name].[hash:8].[ext]'
  52. }
  53. }
  54. }
  55. }
  56. ]
  57. },
  58. ]
  59. }
  60. }

用babel转义js文件 babel-loader @babel/preset-env @babel/core

babel-loader 和 babel-core的对应关系

  1. babel-loader 8.x 对应babel-core 7.x
  2. babel-loader 7.x 对应babel-core 6.x
  1. // webpack.config.js
  2. module.exports = {
  3. // 省略其它配置 ...
  4. module:{
  5. rules:[
  6. {
  7. test:/\.js$/,
  8. use:{
  9. loader:'babel-loader',
  10. options:{
  11. presets:['@babel/preset-env']
  12. }
  13. },
  14. exclude:/node_modules/
  15. },
  16. ]
  17. }
  18. }

转换新的api 如(promise、Generator、Set、Maps、Proxy等) @babel/polyfill
  1. // webpack.config.js
  2. const path = require('path')
  3. module.exports = {
  4. entry: ["@babel/polyfill,path.resolve(__dirname,'../src/index.js')"], // 入口文件
  5. }

2.青铜段位

解析vue文件 vue-loader vue-template-compiler vue-style-loader vue

npm i -D vue-loader vue-template-compiler vue-style-loader
npm i -S vue

热更新 webpack-dev-server
  1. const Webpack = require('webpack')
  2. module.exports = {
  3. // ...省略其他配置
  4. devServer:{
  5. port:3000,
  6. hot:true,
  7. contentBase:'../dist'
  8. },
  9. plugins:[
  10. new Webpack.HotModuleReplacementPlugin()
  11. ]
  12. }

区分开发环境和生产环境

开发环境主要实现的是热更新,不用压缩代码

生产环境主要实现的是压缩代码,提取css文件,分割代码等

主要用到以下插件

  • webpack-merge 合并配置
  • copy-webpack-plugin 拷贝静态资源
  • optimize-css-assets-wepack-plugin 压缩css
  • uglifyjs-webpack-plugin 压缩js

webpack mode设置production的时候会自动压缩js代码。原则上不需要引入uglifyjs-webpack-plugin进行重复工作。但是optimize-css-assets-webpack-plugin压缩css的同时会破坏原有的js压缩,所以这里我们引入uglifyjs进行压缩

另外还要用到

  • cache-loader
  • thread-loader 加速构建

3.段位提升总结

至此手动配置一个vue初级项目所用到的插件

webpack直属

  • webpack
  • webpack-cli
  • webpack-dev-server 热更新
  • webpack-merge

vue相关

  • vue 需要安装在项目dependencies里
  • vue-loader
  • vue-template-compiler
  • vue-style-loader

css 相关 用sass

  • css loader
  • style-loader
  • sass
  • sass-loader
  • postcss-loader
  • autoprefixer

js 相关

  • babel-loader
  • @babel/core
  • @babel/preset-env

压缩、拆分、合并相关

  • extract-text-webpack-plugin 拆分多个css
  • html-webpack-plugin
  • mini-css-extract-plugin 拆分css
  • optimize-css-assets-webpack-plugin 压缩css
  • uglifyjs-webpack-plugin 压缩js

其他

  • thread-loader
  • cache-loader
  • clean-webpack-plugin 清除残留

4.优化打包速度

缩小文件搜索范围
  • alias: 当我们代码中出现 import 'vue'时, webpack会采用向上递归搜索的方式去node_modules 目录下找。为了减少搜索范围我们可以直接告诉webpack去哪个路径下查找。也就是别名(alias)的配置。
  • include exclude 同样配置include exclude也可以减少webpack loader的搜索转换时间。
  • noParse 当我们代码中使用到import jq from 'jquery'时,webpack会去解析jq这个库是否有依赖其他的包。但是我们对类似jquery这类依赖库,一般会认为不会引用其他的包(特殊除外,自行判断)。增加noParse属性,告诉webpack不必解析,以此增加打包速度。
  • extensionswebpack会根据extensions`定义的后缀查找文件(频率较高的文件类型优先写在前面)

5.扩展

友好的命令行显示 friendly-errors-webpack-plugin
  1. const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
  2. new FriendlyErrorsWebpackPlugin()
  3. stats: 'errors-only' //附加的一项配置