webpack基础开发环境配置

package.json中需要引入的基础依赖

{
  "name": "XXX",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {

//基础类
    "webpack": "^4.41.6",
    "webpack-cli": "^3.3.12",
    "thread-loader": "^2.1.3",//多进程打包
    "webpack-dev-server": "^3.10.3",//运行指令 npx webpack-dev-server
    "add-asset-html-webpack-plugin": "^3.1.3",//将某个文件打包输出去,并在html中自动引入该资源
//js
    "@babel/core": "^7.8.4",//babel核心库
    "@babel/polyfill": "^7.8.3",//全部js兼容性处理
    "@babel/preset-env": "^7.8.4",//基本js兼容性处理,高级语法不能转换
    "core-js": "^3.6.4",//按需加载js兼容性处理
    "babel": "^6.23.0",
    "babel-loader": "^8.0.6",
    "eslint": "^6.8.0",//只检查自己写的源代码,第三方的库是不用检查的
    "eslint-loader": "^3.0.3",//语法检查
    "eslint-config-airbnb-base": "^14.0.0",
    "eslint-plugin-import": "^2.20.1",
//html&css&img&other
    "html-webpack-plugin": "^3.2.0",//复制指定HTML文件,自动引入打包输出的所有资源(JS/CSS)
    "html-loader": "^0.5.5",//处理html中img
    "style-loader": "^1.1.3",//处理css
    "css-loader": "^3.4.2",//处理css
    "url-loader": "^3.0.0",//处理图片资源
    "file-loader": "^5.0.2",//打包其他资源
    "mini-css-extract-plugin": "^0.9.0",//提取css单独成文件
    "optimize-css-assets-webpack-plugin": "^5.0.3",//压缩css
    "postcss-loader": "^3.0.0",//css兼容性处理,配置搜索browserslist,用开发环境需设置node环境变量:process.env.NODE_ENV = development
    "postcss-preset-env": "^6.7.0",//css兼容性处理
//less
    "less": "^3.13.1",//处理less
    "less-loader": "^5.0.0",//处理less

  },
  "dependencies": {
    "jquery": "^3.4.1"
  },
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  "eslintConfig": {
    "extends": "airbnb-base",
    "env": {
      "browser": true
    }
  },
  "sideEffects": [
    "*.css"
  ],
  "description": ""
}


基础配置代码webpack.config.js

/*
  开发环境配置:能让代码运行
    运行项目指令:
      webpack 会将打包结果输出出去
      npx webpack-dev-server 只会在内存中编译打包,没有输出
*/

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
//dll技术 -->webpack.dll.js
const webpack = require('webpack');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');


// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader',
  {
    // 还需要在package.json中定义browserslist
    loader: 'postcss-loader',
    options: {
      ident: 'postcss',
      plugins: () => [require('postcss-preset-env')()]
    }
  }
];


module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.[contenthash:5].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        // 在package.json中eslintConfig --> airbnb
        test: /.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
      	// 以下loader只会匹配一个
      	// 注意:不能有两个配置处理同一种类型文件
      	oneOf: [
          {
            test: /.css$/,
            use: [...commonCssLoader]
          },
          {
            test: /.less$/,
            use: [...commonCssLoader, 'less-loader']
          },
          /*
            正常来讲,一个文件只能被一个loader处理。
            当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
              先执行eslint 在执行babel
          */
          {
            test: /.js$/,
            exclude: /node_modules/,
            use: [
              /* 
                开启多进程打包。 
                进程启动大概为600ms,进程通信也有开销。
                只有工作消耗时间比较长,才需要多进程打包
              */
              {
                loader: 'thread-loader',
                options: {
                  workers: 2 // 进程2个
                }
              },
              {
                loader: 'babel-loader',
                options: {
                  presets: [
                    [
                      '@babel/preset-env',
                      {
                        useBuiltIns: 'usage',
                        corejs: { version: 3 },
                        targets: {
                          chrome: '60',
                          firefox: '50'
                        }
                      }
                    ]
                  ],
                  // 开启babel缓存
                  // 第二次构建时,会读取之前的缓存
                  cacheDirectory: true
                }
              }
            ]
          },
          {
            // 处理图片资源
            test: /.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              // 关闭es6模块化
              esModule: false,
              outputPath: 'imgs'
            }
          },
          {
            // 处理html中img资源
            test: /.html$/,
            loader: 'html-loader'
          },
          {
            // 处理其他资源
            exclude: /.(html|js|css|less|jpg|png|gif)/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.[contenthash:5].html',
      // 压缩html代码
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    }),
    new MiniCssExtractPlugin({
      filename: 'css/built.css'
    }),
    // 压缩css
    new OptimizeCssAssetsWebpackPlugin(),
    // 告诉webpack哪些库不参与打包,同时使用时的名称也得变~
    new webpack.DllReferencePlugin({
      manifest: resolve(__dirname, 'dll/manifest.json')
    }),
    // 将某个文件打包输出去,并在html中自动引入该资源
    new AddAssetHtmlWebpackPlugin({
      filepath: resolve(__dirname, 'dll/jquery.js')
    })
  ],
  mode: 'development',
  // 生产环境下会自动压缩js代码
  //mode: 'production',
  //externals和dll是相同目的两种方法,externals引入外部路径,dll适合自己打包库
  //externals: {
  //  // 拒绝jQuery被打包进来
  //  jquery: 'jQuery'
  //},
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  },
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    // 开启HMR功能
    // 当修改了webpack配置,新配置要想生效,必须重新webpack服务
    //hot: true
  }
};

webpack.dll.js

/*
  使用dll技术,对某些库(第三方库:jquery、react、vue...)进行单独打包
    当你运行 webpack 时,默认查找 webpack.config.js 配置文件
    需求:需要运行 webpack.dll.js 文件
      --> webpack --config webpack.dll.js
*/

const { resolve } = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    // 最终打包生成的[name] --> jquery
    // ['jquery'] --> 要打包的库是jquery
    jquery: ['jquery'],
  },
  output: {
    filename: '[name].js',
    path: resolve(__dirname, 'dll'),
    library: '[name]_[hash]' // 打包的库里面向外暴露出去的内容叫什么名字
  },
  plugins: [
    // 打包生成一个 manifest.json --> 提供和jquery映射
    new webpack.DllPlugin({
      name: '[name]_[hash]', // 映射库的暴露的内容名称
      path: resolve(__dirname, 'dll/manifest.json') // 输出文件路径
    })
  ],
  mode: 'production'
};

原文地址:https://www.cnblogs.com/AaronNotes/p/14507231.html