Webpack 生产环境

文章目录

  • 前言
  • 配置
  • [NPM Scripts](#NPM Scripts)
  • [指定 mode](#指定 mode)
  • 压缩(Minification)
  • [源码映射(Source Mapping)](#源码映射(Source Mapping))
  • [CLI 替代选项](#CLI 替代选项)
  • 后言

前言

hello world欢迎来到前端的新世界


😜当前文章系列专栏:webpack

🐱‍👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出)🌹

💖感谢大家支持!您的观看就是作者创作的动力

配置

development(开发环境) 和 production(生产环境) 这两个环境下的构建目标存在着巨大差异。在开发环境中,我们需要:强大的 source map 和一个有着 live reloading(实时重新加载) hot module replacement(热模块替换) 能力的 localhost server。而生产环境目标则转移至其他方面,关注点在于压缩 bundle、更轻量的 source map、资源优化等,通过这些优化方式改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。

虽然,以上我们将 生产环境 和 开发环境 做了细微区分,但是,请注意,我们还是会遵循不重复原则(Don't repeat yourself - DRY),保留一个 "common(通用)" 配置。为了将这些配置合并在一起,我们将使用一个名为 webpack-merge 的工具。此工具会引用 "common" 配置,因此我们不必再在环境特定(environment-specific)的配置中编写重复代码。

我们先从安装 webpack-merge 开始,并将之前指南中已经成型的那些代码进行分离:

javascript 复制代码
npm install --save-dev webpack-merge

project

javascript 复制代码
  webpack-demo
  |- package.json
  |- package-lock.json
- |- webpack.config.js
+ |- webpack.common.js
+ |- webpack.dev.js
+ |- webpack.prod.js
  |- /dist
  |- /src
    |- index.js
    |- math.js
  |- /node_modules

**webpack.common.js **

javascript 复制代码
+ const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
+
+ module.exports = {
+   entry: {
+     app: './src/index.js',
+   },
+   plugins: [
+     new HtmlWebpackPlugin({
+       title: 'Production',
+     }),
+   ],
+   output: {
+     filename: '[name].bundle.js',
+     path: path.resolve(__dirname, 'dist'),
+     clean: true,
+   },
+ };

webpack.dev.js

javascript 复制代码
+ const { merge } = require('webpack-merge');
+ const common = require('./webpack.common.js');
+
+ module.exports = merge(common, {
+   mode: 'development',
+   devtool: 'inline-source-map',
+   devServer: {
+     static: './dist',
+   },
+ });

webpack.prod.js

javascript 复制代码
+ const { merge } = require('webpack-merge');
+ const common = require('./webpack.common.js');
+
+ module.exports = merge(common, {
+   mode: 'production',
+ });

现在,在 webpack.common.js 中,我们设置了 entryoutput 配置,并且在其中引入这两个环境公用的全部插件。在 webpack.dev.js 中,我们将 mode 设置为 development,并且为此环境添加了推荐的 devtool(强大的 source map)和devServer配置。最后,在 webpack.prod.js 中,我们将 mode 设置为 production,其中会引入之前在 tree shaking 指南中介绍过的 TerserPlugin。

注意,在环境特定的配置中使用 merge() 功能,可以很方便地引用 ​webpack.dev.js​ 和 ​webpack.prod.js​ 中公用的 common 配置。webpack-merge 工具提供了各种 merge(合并) 高级功能,但是在我们的用例中,无需用到这些功能。

NPM Scripts

现在,我们把 scripts 重新指向到新配置。让 npm start script 中 webpack-dev-server, 使用 ​webpack.dev.js​, 而让 npm run build script 使用 ​webpack.prod.js​:

package.json

javascript 复制代码
  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "src/index.js",
    "scripts": {
-     "start": "webpack serve --open",
+     "start": "webpack serve --open --config webpack.dev.js",
-     "build": "webpack"
+     "build": "webpack --config webpack.prod.js"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "express": "^4.15.3",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^4.30.0",
      "webpack-dev-middleware": "^1.12.0",
      "webpack-dev-server": "^2.9.1",
      "webpack-merge": "^4.1.0",
      "xml-loader": "^1.2.1"
    }
  }

随便运行下这些脚本,然后查看输出结果的变化,然后我们会继续添加一些 生产环境 配置。

指定 mode

许多library通过与process.env.NODE_ENV环境变量关联,以决定 library 中应该引用哪些内容。例如,当process.env.NODE_ENV 没有被设置为 'production' 时,某些 library 为了使调试变得容易,可能会添加额外的 log(日志记录) 和 test(测试) 功能。并且,在使用 process.env.NODE_ENV === 'production' 时,一些 library 可能针对具体用户的环境,删除或添加一些重要代码,以进行代码执行方面的优化。从webpack v4开始, 指定 mode 会自动地配置 DefinePlugin
webpack.prod.js

javascript 复制代码
  const { merge } = require('webpack-merge');
  const common = require('./webpack.common.js');

  module.exports = merge(common, {
    mode: 'production',
  });

Tip

技术上讲,NODE_ENV 是一个由Node.js暴露给执行脚本的系统环境变量。通常用于决定在开发环境与生产环境(dev-vs-prod)下,server tools(服务期工具)、build scripts(构建脚本) 和 client-side libraries(客户端库) 的行为。然而,与预期相反,在构建脚本 webpack.config.js process.env.NODE_ENV 并没有被设置为 "production",请查看 #2537。因此,在 webpack 配置文件中,process.env.NODE_ENV === 'production' ? '[name].[contenthash].bundle.js' : '[name].bundle.js' 这样的条件语句,无法按照预期运行。

如果你正在使用像 react 这样的 library,那么在添加此 DefinePlugin 插件后,你应该看到 bundle 大小显著下降。还要注意,任何位于 /src 的本地代码都可以关联到 process.env.NODE_ENV 环境变量,所以以下检查也是有效的:
src/index.js

javascript 复制代码
  import { cube } from './math.js';
+
+ if (process.env.NODE_ENV !== 'production') {
+   console.log('Looks like we are in development mode!');
+ }

  function component() {
    const element = document.createElement('pre');

    element.innerHTML = [
      'Hello webpack!',
      '5 cubed is equal to ' + cube(5)
    ].join('\n\n');

    return element;
  }

  document.body.appendChild(component());

压缩(Minification)

在生产模式下,Webpack v4+将默认压缩您的代码。

注意,虽然生产环境下默认使用 TerserPlugin ,并且也是代码压缩方面比较好的选择,但是还有一些其他可选择项。以下有几个同样很受欢迎的插件:

  • ClosureWebpackPlugin
    如果决定尝试一些其他压缩插件,确保新插件也会按照 tree shake 指南中所陈述的具有删除未引用代码dead code的能力,并将它作为 optimization.minimizer

源码映射(Source Mapping)

我们鼓励你在生产环境中启用 source map,因为它们对 debug(调试源码) 和运行 benchmark tests(基准测试) 很有帮助。虽然有着如此强大的功能,然而还是应该针对生产环境用途,选择一个可以快速构建的推荐配置(更多选项请查看 devtool)。对于本指南,我们将在 生产环境 中使用 source-map 选项,而不是我们在 开发环境 中用到的 inline-source-map:

webpack.prod.js

javascript 复制代码
  const { merge } = require('webpack-merge');
  const common = require('./webpack.common.js');

  module.exports = merge(common, {
    mode: 'production',
+   devtool: 'source-map',
  });

Tip

避免在生产中使用 inline-*** 和 eval-***,因为它们会增加 bundle 体积大小,并降低整体性能。

CLI 替代选项

上述许多选项都可以通过命令行参数进行设置。例如, ​optimize-minimize​ 可以使用 ​--optimization-minimize​ 进行设置,mode 可以使用 ​--mode​ 进行设置。运行 ​npx webpack --help=verbose​ 可以查看所有关于 CLI 的可用参数。

虽然这种简写方式很有用处,但我们还是建议通过 webpack 配置文件的方式进行使用,这样可以提高可配置能力。

后言

创作不易,要是本文章对广大读者有那么一点点帮助 不妨三连支持一下,您的鼓励就是博主创作的动力

相关推荐
你的电影很有趣11 分钟前
lesson71:Node.js与npm基础全攻略:2025年最新特性与实战指南
前端·npm·node.js
闲蛋小超人笑嘻嘻30 分钟前
find数组方法详解||Vue3 + uni-app + Wot Design(wd-picker)使用自定义插槽内容写一个下拉选择器
前端·javascript·uni-app
小牛itbull1 小时前
初始化electron项目运行后报错 electron uninstall 解决方法
前端·javascript·electron
闲蛋小超人笑嘻嘻1 小时前
前端面试十四之webpack和vite有什么区别
前端·webpack·node.js
guslegend1 小时前
Webpack5 第五节
webpack
特立独行的猫a1 小时前
JSNES游戏模拟器在 Node.js 环境下的测试使用及高清显示优化
游戏·node.js·nes·jsnes
rggrgerj2 小时前
Vue3 组件完全指南代码
前端·javascript·vue.js
golang学习记3 小时前
从0死磕全栈之Next.js App Router动态路由详解:从入门到实战
前端
huangql5203 小时前
基于前端+Node.js 的 Markdown 笔记 PDF 导出系统完整实战
前端·笔记·node.js
在逃的吗喽3 小时前
Vue3新变化
前端·javascript·vue.js