当前位置: 首页> 健康> 知识 > 互联网广告代理商_企业管理软件价格_打开浏览器直接进入网站_网站网络营销推广

互联网广告代理商_企业管理软件价格_打开浏览器直接进入网站_网站网络营销推广

时间:2025/7/11 17:59:18来源:https://blog.csdn.net/2302_76329106/article/details/143843641 浏览次数:0次
互联网广告代理商_企业管理软件价格_打开浏览器直接进入网站_网站网络营销推广

九、环境变量

想要消除 webpack.config.js 在 开发环境 和 生产环境 之间的差异,你可能需要环境变量(environment variable)。

webpack 命令行 环境配置 的 --env 参数,可以允许你传入任意数量的环境变量。而在 webpack.config.js 中可以访问到这些环境变量。例如,--env production--env NODE_ENV=localNODE_ENV 通常约定用于定义环境类型,查看 这里)。

npx webpack --env NODE_ENV=local --env production --progress

Tip
如果设置 env 变量,却没有赋值,--env production 默认表示将 env.production 设置为 true。还有许多其他可以使用的语法。更多详细信息,请查看 webpack CLI 文档。

对于我们的 webpack 配置,有一个必须要修改之处。通常,module.exports 指向配置对象。要使用 env 变量,你必须将 module.exports 转换成一个函数:

webpack.config.js

const path = require('path');module.exports = env => {// Use env.<YOUR VARIABLE> here:console.log('NODE_ENV: ', env.NODE_ENV); // 'local'console.log('Production: ', env.production); // truereturn {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},};
};

十、安装

本指南介绍了安装 webpack 的各种方法。

1、前提条件

在开始之前,请确保安装了 Node.js 的最新版本。使用 Node.js 最新的长期支持版本(LTS - Long Term Support),是理想的起步。 使用旧版本,你可能遇到各种问题,因为它们可能缺少 webpack 功能, 或者缺少相关 package。

2、本地安装

最新的 webpack 正式版本是:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

要安装最新版本或特定版本,请运行以下命令之一:

npm install --save-dev webpack
# 或指定版本
npm install --save-dev webpack@<version>

Tip
是否使用 --save-dev 取决于你的应用场景。假设你仅使用 webpack 进行构建操作,那么建议你在安装时使用 --save-dev 选项,因为可能你不需要在生产环境上使用 webpack。如果需要应用于生产环境,请忽略 --save-dev 选项。

如果你使用 webpack v4+ 版本,你还需要安装 CLI。

npm install --save-dev webpack-cli

对于大多数项目,我们建议本地安装。这可以在引入重大更新(breaking change)版本时,更容易分别升级项目。 通常会通过运行一个或多个 npm scripts 以在本地 node_modules 目录中查找安装的 webpack, 来运行 webpack:

"scripts": {"build": "webpack --config webpack.config.js"
}

Tip
想要运行本地安装的 webpack,你可以通过 node_modules/.bin/webpack 来访问它的二进制版本。另外,如果你使用的是 npm v5.2.0 或更高版本,则可以运行 npx webpack 来执行。

3、全局安装

通过以下 NPM 安装方式,可以使 webpack 在全局环境下可用:

npm install --global webpack

Warning
不推荐 全局安装 webpack。这会将你项目中的 webpack 锁定到指定版本,并且在使用不同的 webpack 版本的项目中, 可能会导致构建失败。

4、最新体验版本

如果你热衷于使用最新版本的 webpack,你可以使用以下命令安装 beta 版本, 或者直接从 webpack 的仓库中安装:

npm install --save-dev webpack@next
# 或特定的 tag/分支
npm install --save-dev webpack/webpack#<tagname/branchname>

Warning
安装这些最新体验版本时要小心!它们可能仍然包含 bug,因此不应该用于生产环境。

十一、模块热替换

模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新所有类型的模块, 而无需完全刷新。本页面重点介绍其 实现,而 概念 页面提供了更多关于 它的工作原理以及为什么它有用的细节。

Warning
HMR 不适用于生产环境,这意味着它应当用于开发环境。更多详细信息, 请查看 生产环境 指南。

1、启用 HMR

此功能可以很大程度提高生产效率。我们要做的就是更新 webpack-dev-server 配置, 然后使用 webpack 内置的 HMR 插件。我们还要删除掉 print.js 的入口起点, 因为现在已经在 index.js 模块中引用了它。

Tip
如果你在技术选型中使用了 webpack-dev-middleware 而没有使用 webpack-dev-server,请使用 webpack-hot-middleware 依赖包,以在你的自定义服务器或应用程序上启用 HMR。

webpack.config.js

  const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {entry: {app: './src/index.js',
-      print: './src/print.js',},devtool: 'inline-source-map',devServer: {contentBase: './dist',
+     hot: true,},plugins: [// new CleanWebpackPlugin(['dist/*']) for < v2 versions of CleanWebpackPluginnew CleanWebpackPlugin(),new HtmlWebpackPlugin({title: 'Hot Module Replacement',}),],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

现在,我们来修改 index.js 文件,以便当 print.js 内部发生变更时可以告诉 webpack 接受更新的模块。

index.js

  import _ from 'lodash';import printMe from './print.js';function component() {const element = document.createElement('div');const btn = document.createElement('button');element.innerHTML = _.join(['Hello', 'webpack'], ' ');btn.innerHTML = 'Click me and check the console!';btn.onclick = printMe;element.appendChild(btn);return element;}document.body.appendChild(component());
+
+ if (module.hot) {
+   module.hot.accept('./print.js', function() {
+     console.log('Accepting the updated printMe module!');
+     printMe();
+   })
+ }

更改 print.jsconsole.log 的输出内容,你将会在浏览器中看到如下的输出 (不要担心现在 button.onclick = printMe() 的输出,我们稍后也会更新该部分)。

print.js

  export default function printMe() {
-   console.log('I get called from print.js!');
+   console.log('Updating print.js...');}

console

[HMR] Waiting for update signal from WDS...
main.js:4395 [WDS] Hot Module Replacement enabled.
+ 2main.js:4395 [WDS] App updated. Recompiling...
+ main.js:4395 [WDS] App hot update...
+ main.js:4330 [HMR] Checking for updates on the server...
+ main.js:10024 Accepting the updated printMe module!
+ 0.4b8ee77….hot-update.js:10 Updating print.js...
+ main.js:4330 [HMR] Updated modules:
+ main.js:4330 [HMR]  - 20

2、通过 Node.js API

在 Node.js API 中使用 webpack dev server 时,不要将 dev server 选项放在 webpack 配置对象中。而是在创建时, 将其作为第二个参数传递。例如:

new WebpackDevServer(compiler, options)

想要启用 HMR,还需要修改 webpack 配置对象,使其包含 HMR 入口起点。webpack-dev-server 依赖包中具有一个叫做 addDevServerEntrypoints 的方法,你可以通过使用这个方法来实现。这是关于如何使用的一个基本示例:

dev-server.js

const webpackDevServer = require('webpack-dev-server');
const webpack = require('webpack');const config = require('./webpack.config.js');
const options = {contentBase: './dist',hot: true,host: 'localhost',
};webpackDevServer.addDevServerEntrypoints(config, options);
const compiler = webpack(config);
const server = new webpackDevServer(compiler, options);server.listen(8080, 'localhost', () => {console.log('dev server listening on port 8080');
});

Tip
如果你正在使用 webpack-dev-middleware,可以通过 webpack-hot-middleware 依赖包,在自定义 dev server 中启用 HMR。

3、问题

模块热替换可能比较难以掌握。为了说明这一点,我们回到刚才的示例中。如果你继续点击示例页面上的按钮, 你会发现控制台仍在打印旧的 printMe 函数。

这是因为按钮的 onclick 事件处理函数仍然绑定在旧的 printMe 函数上。

为了让 HMR 正常工作,我们需要更新代码,使用 module.hot.accept 将其绑定到新的 printMe 函数上:

index.js

  import _ from 'lodash';import printMe from './print.js';function component() {const element = document.createElement('div');const btn = document.createElement('button');element.innerHTML = _.join(['Hello', 'webpack'], ' ');btn.innerHTML = 'Click me and check the console!';btn.onclick = printMe;  // onclick event is bind to the original printMe functionelement.appendChild(btn);return element;}- document.body.appendChild(component());
+ let element = component(); // 存储 element,以在 print.js 修改时重新渲染
+ document.body.appendChild(element);if (module.hot) {module.hot.accept('./print.js', function() {console.log('Accepting the updated printMe module!');
-     printMe();
+     document.body.removeChild(element);
+     element = component(); // 重新渲染 "component",以便更新 click 事件处理函数
+     document.body.appendChild(element);})}

4、HMR 加载样式

借助于 style-loader,使用模块热替换来加载 CSS 实际上极其简单。此 loader 在幕后使用了 module.hot.accept,在 CSS 依赖模块更新之后,会将其 patch(修补) 到 <style> 标签中。

首先使用以下命令安装两个 loader :

npm install --save-dev style-loader css-loader

然后更新配置文件,使用这两个 loader。

webpack.config.js

  const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = {entry: {app: './src/index.js',},devtool: 'inline-source-map',devServer: {contentBase: './dist',hot: true,},
+   module: {
+     rules: [
+       {
+         test: /\.css$/,
+         use: ['style-loader', 'css-loader'],
+       },
+     ],
+   },plugins: [// 对于 CleanWebpackPlugin 的 v2 versions 以下版本,使用 new CleanWebpackPlugin(['dist/*'])new CleanWebpackPlugin(),new HtmlWebpackPlugin({title: 'Hot Module Replacement',}),],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

如同 import 模块,热加载样式表同样很简单:

project

  webpack-demo| - package.json| - webpack.config.js| - /dist| - bundle.js| - /src| - index.js| - print.js
+   | - styles.css

styles.css

body {background: blue;
}

index.js

  import _ from 'lodash';import printMe from './print.js';
+ import './styles.css';function component() {const element = document.createElement('div');const btn = document.createElement('button');element.innerHTML = _.join(['Hello', 'webpack'], ' ');btn.innerHTML = 'Click me and check the console!';btn.onclick = printMe;  // onclick event is bind to the original printMe functionelement.appendChild(btn);return element;}let element = component();document.body.appendChild(element);if (module.hot) {module.hot.accept('./print.js', function() {console.log('Accepting the updated printMe module!');document.body.removeChild(element);element = component(); // Re-render the "component" to update the click handlerdocument.body.appendChild(element);})}

body 的 style 改为 background: red;,你应该可以立即看到页面的背景颜色随之更改,而无需完全刷新。

styles.css

  body {
-   background: blue;
+   background: red;}

十二、Tree Shaking

tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块语法的 静态结构 特性,例如 importexport。这个术语和概念实际上是由 ES2015 模块打包工具 rollup 普及起来的。

webpack 2 正式版本内置支持 ES2015 模块(也叫做 harmony modules)和未使用模块检测能力。新的 webpack 4 正式版本扩展了此检测能力,通过 package.json"sideEffects" 属性作为标记,向 compiler 提供提示,表明项目中的哪些文件是 “pure(纯正 ES2015 模块)”,由此可以安全地删除文件中未使用的部分。

1、添加一个通用模块

在我们的项目中添加一个新的通用模块文件 src/math.js,并导出两个函数:

project

webpack-demo
|- package.json
|- webpack.config.js
|- /dist|- bundle.js|- index.html
|- /src|- index.js
+ |- math.js
|- /node_modules

src/math.js

export function square(x) {return x * x;
}export function cube(x) {return x * x * x;
}

需要将 mode 配置设置成development,以确定 bundle 不会被压缩:

webpack.config.js

const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},
+ devtool: 'source-map',
+ mode: 'development',
+ optimization: {
+   usedExports: true,
+ },
};

配置完这些后,更新入口脚本,使用其中一个新方法,并且为了简化示例,我们先将 lodash 删除:

src/index.js

- import _ from 'lodash';
+ import { cube } from './math.js';function component() {
-   const element = document.createElement('div');
+   const element = document.createElement('pre');-   // Lodash, now imported by this script
-   element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+   element.innerHTML = [
+     'Hello webpack!',
+     '5 cubed is equal to ' + cube(5)
+   ].join('\n\n');return element;}document.body.appendChild(component());

注意,我们没有从 src/math.js 模块中 import 另外一个 square 方法。这个函数就是所谓的“未引用代码(dead code)”,也就是说,应该删除掉未被引用的 export。现在运行 npm script npm run build,并查看输出的 bundle:

dist/bundle.js (around lines 90 - 100)

/* 1 */
/***/ (function (module, __webpack_exports__, __webpack_require__) {'use strict';/* unused harmony export square *//* harmony export (immutable) */ __webpack_exports__['a'] = cube;function square(x) {return x * x;}function cube(x) {return x * x * x;}
});

注意,上面的 unused harmony export square 注释。如果你观察它下面的代码,你会注意到虽然我们没有引用 square,但它仍然被包含在 bundle 中。我们将在下一节解决这个问题。

2、将文件标记为 side-effect-free(无副作用)

在一个纯粹的 ESM 模块世界中,很容易识别出哪些文件有 side effect。然而,我们的项目无法达到这种纯度,所以,此时有必要提示 webpack compiler 哪些代码是“纯粹部分”。

通过 package.json 的 "sideEffects" 属性,来实现这种方式。

{"name": "your-project","sideEffects": false
}

如果所有代码都不包含 side effect,我们就可以简单地将该属性标记为 false,来告知 webpack,它可以安全地删除未用到的 export。

Tip
“side effect(副作用)” 的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个 export 或多个 export。举例说明,例如 polyfill,它影响全局作用域,并且通常不提供 export。

如果你的代码确实有一些副作用,可以改为提供一个数组:

{"name": "your-project","sideEffects": ["./src/some-side-effectful-file.js"]
}

此数组支持简单的 glob 模式匹配相关文件。其内部使用了 glob-to-regexp(支持:***{a,b}[a-z])。如果匹配模式为 *.css,且不包含 /,将被视为 **/*.css

Tip
注意,所有导入文件都会受到 tree shaking 的影响。这意味着,如果在项目中使用类似 css-loader 并 import 一个 CSS 文件,则需要将其添加到 side effect 列表中,以免在生产模式中无意中将它删除:

{"name": "your-project","sideEffects": ["./src/some-side-effectful-file.js", "*.css"]
}

最后,还可以在 module.rules 配置选项 中设置 "sideEffects"

具体操作入下:

  • 安装依赖
yarn add webpack-cli webpack-dev-server css-loader style-loader -D
// 注意webpack-cli 与 webpack-dev-server的版本匹配
  • project
webpack-demo
|- package.json
|- webpack.config.js
|- /dist|- bundle.js|- index.html
|- /src|- index.js|- math.js
+ |- some-side-effectful-file.js
+ |- style.css
|- /node_modules
  • src/some-side-effectful-file.js
export default 'side effectful'
  • src/style.css
body {background-color: blueviolet;
}
  • src/index.js
import { cube } from './math.js'+import Greeting from './some-side-effectful-file'
+import './style.css'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())
  • webpack.config.js
const path = require('path')module.exports = {mode: 'development',entry: {index: './src/index.js',},output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},optimization: {usedExports: true,},
+ module: {
+  rules: [
+    {
+      test: /\.css$/,
+      use: ['style-loader', 'css-loader']
+    }
+  ]
+ },
+ devServer: {
+   contentBase: path.join(__dirname, 'dist')
+ }
};
  • package.json
{"name": "webpack-demo","version": "1.0.0","description": "","private": true,
+ "sideEffects": false,"scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack","start": "webpack-dev-server"},"keywords": [],"author": "","license": "ISC","devDependencies": {"css-loader": "^5.0.2","style-loader": "^2.0.0","webpack": "^5.21.0","webpack-cli": "3.3.12","webpack-dev-server": "^3.11.2"}
}
  • 开发环境运行项目
npm run build

结果发现,style.csssome-side-effectful-file.js都被打包了。

  • 生产环境运行项目

修改webpack.config.js

const path = require('path')module.exports = {
- mode: 'development',
+ mode: 'production',entry: {index: './src/index.js',},output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),},optimization: {usedExports: true,},module: {rules: [{test: /\.css$/,use: ['style-loader', 'css-loader']}]},devServer: {contentBase: path.join(__dirname, 'dist')}
};

结果发现,style.csssome-side-effectful-file.js不在打包的目标文件了。

  • 修改 package.json
{"name": "webpack-demo","version": "1.0.0","description": "","private": true,
- "sideEffects": false,
+ "sideEffects": ["./src/some-side-effectful-file.js", "*.css"],"scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack","start": "webpack-dev-server"},"keywords": [],"author": "","license": "ISC","devDependencies": {"css-loader": "^5.0.2","style-loader": "^2.0.0","webpack": "^5.21.0","webpack-cli": "3.3.12","webpack-dev-server": "^3.11.2"}
}
关键字:互联网广告代理商_企业管理软件价格_打开浏览器直接进入网站_网站网络营销推广

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: