webpack 配置实战

220 阅读5分钟

github.com/17698753015…

  1. 这是一个使用 Vue CLI 创建出来的 Vue 项目基础结构
  2. 有所不同的是这里我移除掉了 vue-cli-service(包含 webpack 等工具的黑盒工具)
  3. 这里的要求就是直接使用 webpack 以及你所了解的周边工具、Loader、Plugin 还原这个项目的打包任务
  4. 尽可能的使用上所有你了解到的功能和特性

一、安装、配置 webpack

  • 首先webpack环境
yarn add webpack webpack-cli --dev
  • 初始化webpack.config.js,在根目录下新建
module.exports = { // 可以导出对象,数组, 函数。
	mode: string,
    entry: string|Array<string>,
    moodule: object,
    plugins: Array<object>
}
  • webpack.config.js mini版(会报错这个因为我们没有对里面的less 和 vue 做任何处理)
const path = require('path')

module.exports = {
  mode: 'none',
  entry: './src/main.js', // 以main.js为入口
  output: {
    path: path.join(__dirname, 'dist'), // 打包到这个路径
    filename: 'bundle.js' // 打包后的文件名字
  },
  module: {
  },
  plugins: []
}
// 运行yarn webpack || npx install webpack

二、对vue less 图片 分别处理

  • less 首先对less转换处理
yarn add vue-style-loader css-loader less-loader --dev
module: {
  rules: [
    {
      test: /.less$/,
      use: ['vue-style-loader', 'css-loader', 'less-loader']
    }
  ]
}
// 运行yarn webpack || npx install webpack
// 关于less 的报错会消失
  • 对vue文件处理
    • 注意需要两个模块分开处理 (.css .vue)
yarn add vue-loader style-loader --dev

const VueLoaderPlugin = require('vue-loader/lib/plugin')
module: {
  rules: [
    {
      test: /.less$/,
      use: ['vue-style-loader', 'css-loader', 'less-loader']
    },
    // 对.vue文件处理
    {
        test: /\.vue$/,
        loader: 'vue-loader'
    },
    {
      test: /\.css$/,
      use: [
        'style-loader',
        'css-loader'
      ]
    }
  ]
}
plugins: [
  // 对vue文件处理需要的插件
  new VueLoaderPlugin(),
]
// 基本可以打包了 还有图片没有处理
  • 对图片进行处理
yarn add file-loader --dev[](url)
module: {
  rules: [
    // 处理less
    {
      test: /.less$/,
      use: ['vue-style-loader', 'css-loader', 'less-loader']
    },
    // 对.vue文件处理
    {
        test: /\.vue$/,
        loader: 'vue-loader'
    },
    {
      test: /\.css$/,
      use: [
        'style-loader',
        'css-loader'
      ]
    },
    // 对图片进行处理
    {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          esModule: false, // ⚠️注意: esModule设为false可以避免img-src获取图片不生效。
          name: '[name].[ext]?[hash]'
        }
     }
  ]
}
plugins: [
  // 对vue文件处理需要的插件
  new VueLoaderPlugin(),
]
// 最初级webpack打包已经完成
  • 对html进行处理
    • 想一想我们虽根据入口文件将都打包起来,但是最终我们需要将 js css 放到html里面的这样才能够展示出来。loader 只能够匹配某一类文件在文件内部处理。并不能跨文件处理。这个时候就plugins处理
yarn add html-webpack-plugin --dev
const HtmlWebpackPlugin = require('html-webpack-plugin')
....
plugins: [
  new HtmlWebpackPlugin({ // 使用这个插件可以将处理打包好的css js 引入这个文件里面。可以使用指定模版文件也可以使用默认的index.html。具体使用查询API
      title: 'my-app',
      filename: 'index.html',
      template: 'public/index.html'
  }),
]
// 这个时候使用yarn webpack 
// dist 目录就会生成你想要的
// 做个时候你在dist目录起一个服务。(如果有引入路径问题自行在output> publicPath: 自己设置。)
// 打开就可以了

三、对webpack打包进行优化

  • webpack-dev-server安装在项目里面方便使用。
yarn add webpack-dev-server --dev

yarn webpack-dev-server --open 
// http://localhost:8080/
// 需要配置代理和其他配置自行查询文档
  • 拆分css 如果有相同的提取出来 (目前内部样式表)
yarn add mini-css-extract-plugin --dev // 提取css 到单独文件里面
// loader
{
  test: /.less$/,
  use: [
    // 'style-loader',
    MiniCssExtractPlugin.loader,
    'css-loader',
    'less-loader']
},
{
  test: /\.css$/,
  use: [
    // 'style-loader', // 使用<style></style>
    MiniCssExtractPlugin.loader, // <link/>
    'css-loader'
  ]
},
plugins: [
	new MiniCssExtractPlugin({ // 配置根据需求查询文档
      filename: '[hash].[name].css'
    })
]
  • 在生产模式下webpack 会默认压缩js 和 html 但是不会压缩css 这里需要单独的插件
yarn add optimize-css-assets-webpack-plugin --dev
optimization: {
  usedExports: true,
  // 以前是一个模块对应一个函数。concatenateModules是将所有模块放在一个函数当中。
  // 尽可能将函数输出到一个函数里面,既提升了运行效率。又减少了函数的体积。作用域提升。称为: Scope Hoisting
  concatenateModules: true,
  minimizer: [ // webpack 建议将压缩类插件放到minimizer这个数组当中。
    new OptimizeCssAssetsWebpackPlugin(), // 这样写的话就等于告诉webpack
    // 不需要默认的配置所有压缩配置需要自定义。
    // 所有现在默认压缩js的插件不工作了需要重新配置
    new TerserWebpackPlugin()
  ]
},
  • js 使用babel转换
yarn add @babel/core @babel/preset-env babel-loader --dev
{
  test: /\.js$/,
  loader: 'babel-loader',
  options: {
    presets: [ // @babel/preset-env 传递参数需要数组里在创建一个数组。第一个元素为'@babel/preset-env', 第二个元素为一个对象来配置参数。
      ['@babel/preset-env']
    ]
  }
},
  • 性能优化
optimization: {
   usedExports: true,
   splitChunks: { // 将所有公共模块提取出来。
     chunks: 'all'
   },
   // 以前是一个模块对应一个函数。concatenateModules是将所有模块放在一个函数当中。
   // 尽可能将函数输出到一个函数里面,既提升了运行效率。又减少了函数的体积。作用域提升。称为: Scope Hoisting
   concatenateModules: true,
   minimizer: [ // webpack 建议将压缩类插件放到minimizer这个数组当中。
     new OptimizeCssAssetsWebpackPlugin(), // 这样写的话就等于告诉webpack
     // 不需要默认的配置所有压缩配置需要自定义。
     // 所有现在默认压缩js的插件不工作了需要重新配置
     new TerserWebpackPlugin()
   ]
 },

四、配置ESlint并且在webpack中使用

  • 初始化ESlint
yarn add eslint --dev
yarn eslint --init
// 会根据你的选择生成.eslintrc文件
// 需要特殊配置查询文档
// 这个时候配合vscode的eslint 插件。哪个文件有问题就会有提示。
  • eslint 结合 vscode
    • 下载vscode eslint插件就可以看见是否报错。
  • eslint 结合 webpack
    • eslint结合webpack是以loader的模式结合的。
yarn add eslint-loader
{
  test: /\.(js|vue)$/,
  loader: 'eslint-loader',
  enforce: 'pre', // 优先级高于别的
  // 指定检查的目录
  include: [path.resolve(__dirname, 'src')]
}
// 然后运行yarn webpack 打包就可以看见语法的报错。

五、配置stylelint并且在webpack中使用

  • 初始化ESlint
yarn add stylelint --dev
yarn add stylelint-config-css-modules --dev
yarn add stylelint-config-prettier --dev
yarn add stylelint-config-rational-order --dev
yarn add stylelint-config-standard --dev
yarn add stylelint-declaration-block-no-ignored-properties --dev
yarn add stylelint-order --dev
  • 在根目录新建.stylelintrc.js
module.exports = {
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-css-modules",
    "stylelint-config-rational-order",
    "stylelint-config-prettier"
  ],
  "plugins": ["stylelint-order", "stylelint-declaration-block-no-ignored-properties"],
  "rules": {
    "no-descending-specificity": null,
    "plugin/declaration-block-no-ignored-properties": true,
    "at-rule-no-unknown": null
  }
}
  • stylelint 结合 vscode
    • 下载vscode stylelint插件就可以看见是否报错。
  • style结合webpack ------stylelint-webpack-plugin
const StyleLintPlugin = require('stylelint-webpack-plugin')
plugins:[
   new StyleLintPlugin({
      files: ['src/**/*.vue', 'src/**/*.less']
   })
]

  • package.json 修复错误css代码
"scripts": {
    "style:fix": "stylelint 'src/**/*.l?(e|c)ss' 'src/**/*.vue' --fix"
  },

六、独立拆分开发和生产的webpack配置

  • 新建webpack配置文件
    • webpack.dev.js // 开发插件文件配置
    • webpack.prod.js // 生产插件文件配置
    • webpack.common.js // 公共文件配置
    • 三个文件夹分别导出一个对象。
    • 我们需要webpack-merge这个插件组合起来
const common = require('./weebpack.common') 
const { merge } = require('webpack-merge') // 会将两个对象合并。
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')

module.exports = merge(common, {
  mode: 'production',
  devtool: false,
  plugins: [
    new CleanWebpackPlugin(),
    new CopyPlugin({
      patterns: [
        { from: 'public' }
      ]
    })
  ]
})
// 接下来使用yarn webpack --config webpack-prod.js 即可打包生产包。
// 开发同理。

七、根据git hooks 提交检测

  • husky可以实现Git Hooks的使用需求
"scripts": { // 使用 run-all插件合并任务。run-p 并行 run-s 串行
    "stylelint": "stylelint 'src/**/*.l?(e|c)ss' 'src/**/*.vue' --fix",
    "eslint": "eslint 'src/**/*.js' 'src/**/*.vue' --fix",
    "lint": "run-p eslint stylelint",
    "preCommit": "lint-staged"
  },
yarn add husky --dev
// package.json
"husky": {
    "hooks": { // 使用husky插件在检测commit之前执行lint操作。检测代码
      "pre-commit": "npm run lint"
    }
  },
yarn add lint-staged --dev
"lint-staged": {
    "*.js": [
      "eslint",
      "git add"
    ]
  },