1、实现目标

  • 分离开发环境、生产环境配置;
  • 模块化开发;
  • sourceMap 定位警告和错误;
  • 动态生成引入 bundle.js 的 HTML5 文件;
  • 实时编译;
  • 封装编译、打包命令。

2、基础配置

2.1 新建项目目录

image.png

2.2 安装插件

  1. npm i webpack-merge -D
  2. npm install webpack webpack-cli --save-dev

2.3 添加config目录下的webpack代码

webpack.common.js

  1. // webpack.common.js
  2. module.exports = {} // 暂不添加配置

webpack.dev.js

  1. // webpack.dev.js
  2. const { merge } = require('webpack-merge')
  3. const common = require('./webpack.common')
  4. module.exports = merge(common, {}) // 暂不添加配置

webpack.prod.js

  1. // webpack.prod.js
  2. const { merge } = require('webpack-merge')
  3. const common = require('./webpack.common')
  4. module.exports = merge(common, {}) // 暂不添加配置

2.4 entry(入口)

修改 webpack.commom.js:

  1. // webpack.common.js
  2. module.exports = {
  3. // 入口
  4. entry: {
  5. index: './src/index.js',
  6. },
  7. }

2.5 output(出口)

output 属性输出它所创建的 bundle的位置和命名;

生产环境的 output 需要通过 contenthash 值来区分版本和变动,可达到清缓存的效果,而本地环境为了构建效率,则不引人 contenthash。

修改webpack.dev.js

  1. // webpack.dev.js
  2. const { merge } = require('webpack-merge')
  3. const common = require('./webpack.common')
  4. const { resolveApp } = require('./paths');
  5. module.exports = merge(common, {
  6. // 输出
  7. output: {
  8. // bundle 文件名称
  9. filename: '[name].bundle.js',
  10. // bundle 文件路径
  11. path: resolveApp('dist'),
  12. // 编译前清除目录
  13. clean: true
  14. },
  15. })

修改webpack.prod.js

  1. // webpack.prod.js
  2. const { merge } = require('webpack-merge')
  3. const common = require('./webpack.common')
  4. const { resolveApp } = require('./paths');
  5. module.exports = merge(common, {
  6. // 输出
  7. output: {
  8. // bundle 文件名称 【只有这里和开发环境不一样】
  9. filename: '[name].[contenthash].bundle.js',
  10. // bundle 文件路径
  11. path: resolveApp('dist'),
  12. // 编译前清除目录
  13. clean: true
  14. }
  15. })

新增 paths.js,封装路径方法resolveApp:

  1. const fs = require('fs')
  2. const path = require('path')
  3. const appDirectory = fs.realpathSync(process.cwd());
  4. const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
  5. module.exports = {
  6. resolveApp
  7. }

占位符作用

  • [name] - chunk name(例如 [name].js -> app.js)。如果 chunk 没有名称,则会使用其 id 作为名称
  • [contenthash] - 输出文件内容的 md4-hash(例如 [contenthash].js -> 4ea6ff1de66c537eb9b2.js)

2.6 模式(mode)

添加生产环境和开发环境:

  1. module.exports = merge(common, {
  2. // 生产模式
  3. mode: 'production',
  4. })
  5. module.exports = merge(common, {
  6. // 开发环境
  7. mode: 'development',
  8. })

2.7 source-map

使用source-map追踪 error 和 warning,将编译后的代码映射回原始源代码;

  1. module.exports = merge(common, {
  2. mode: 'development',
  3. // 开发环境,开启 source map,编译调试
  4. devtool: 'eval-cheap-module-source-map',
  5. })

打包一下试试:

开发:

  1. npx webpack --config config/webpack.dev.js

image.png

生产:

  1. npx webpack --config config/webpack.prod.js

image.png

2.8 HtmlWebpackPlugin

引入 HtmlWebpackPlugin 插件,生成一个 HTML5 文件, 其中包括使用 script 标签的 body 中的所有 webpack 包;

  1. npm install --save-dev html-webpack-plugin

修改webpack.commom.js:

  1. module.exports = {
  2. plugins: [
  3. // 生成html,自动引入所有bundle
  4. new HtmlWebpackPlugin({
  5. title: 'webpack',
  6. }),
  7. ],
  8. }

2.9 DevServer

  • webpack-dev-server 提供了一个基本的 web server,并且具有实时重新加载功能;
  • webpack-dev-server 默认配置 conpress: true,为每个静态文件开启 gzip compression

安装

  1. npm install --save-dev webpack-dev-server

修改开发环境配置文件webpack.dev.js:

  1. module.exports = merge(common, {
  2. devServer: {
  3. // 告诉服务器位置。
  4. static: {
  5. directory: path.join(__dirname, 'dist'),
  6. },
  7. port: 8888,
  8. hot: true,
  9. },
  10. })

输入命令启动:

  1. npx webpack serve --open --config config/webpack.dev.js

2.10 执行命令

通过 cross-env 配置环境变量,区分开发环境和生产环境。

安装:

  1. npm install --save-dev cross-env

修改 package.json:

  1. {
  2. "scripts": {
  3. "dev": "cross-env NODE_ENV=development webpack serve --open --config config/webpack.dev.js",
  4. "build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js"
  5. },
  6. }

现在可以运行 webpack 指令:

  • npm run dev:本地构建;
  • npm run build:生产打包;

3、本节代码

代码地址:https://gitee.com/linhexs/webpack5/tree/2.practice/