webpack 模块标识符(Module Identifiers)

让我们向项目中再添加一个模块 print.js

project

webpack-demo
|- package.json
|- webpack.config.js
|- /dist
|- /src
  |- index.js
+ |- print.js
|- /node_modules

print.js

+ export default function print(text) {
+   console.log(text);
+ };

src/index.js

  import _ from ‘lodash‘;
+ import Print from ‘./print‘;

  function component() {
    var element = document.createElement(‘div‘);

    // lodash 是由当前 script 脚本 import 导入进来的
    element.innerHTML = _.join([‘Hello‘, ‘webpack‘], ‘ ‘);
+   element.onClick = Print.bind(null, ‘Hello webpack!‘);

    return element;
  }

  document.body.appendChild(component());

再次运行构建,然后我们期望的是,只有 main bundle 的 hash 发生变化,然而……

Hash: d38a06644fdbb898d795
Version: webpack 3.3.0
Time: 1445ms
                          Asset       Size  Chunks                    Chunk Names
 vendor.a7561fb0e9a071baadb9.js     541 kB       0  [emitted]  [big]  vendor
   main.b746e3eb72875af2caa9.js    1.22 kB       1  [emitted]         main
runtime.1400d5af64fc1b7b3a45.js    5.85 kB       2  [emitted]         runtime
                     index.html  352 bytes          [emitted]
   [1] ./src/index.js 421 bytes {1} [built]
   [2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [3] (webpack)/buildin/module.js 517 bytes {0} [built]
   [4] ./src/print.js 62 bytes {1} [built]
   [5] multi lodash 28 bytes {0} [built]
    + 1 hidden module

……我们可以看到这三个文件的 hash 都变化了。这是因为每个 module.id 会基于默认的解析顺序(resolve order)进行增量。也就是说,当解析顺序发生变化,ID 也会随之改变。因此,简要概括:

  • main bundle 会随着自身的新增内容的修改,而发生变化。
  • vendor bundle 会随着自身的 module.id 的修改,而发生变化。
  • runtime bundle 会因为当前包含一个新模块的引用,而发生变化。

第一个和最后一个都是符合预期的行为 -- 而 vendor 的 hash 发生变化是我们要修复的。幸运的是,可以使用两个插件来解决这个问题。第一个插件是 NamedModulesPlugin,将使用模块的路径,而不是数字标识符。虽然此插件有助于在开发过程中输出结果的可读性,然而执行时间会长一些。第二个选择是使用 HashedModuleIdsPlugin,推荐用于生产环境构建:

webpack.config.js

  const path = require(‘path‘);
  const webpack = require(‘webpack‘);
  const CleanWebpackPlugin = require(‘clean-webpack-plugin‘);
  const HtmlWebpackPlugin = require(‘html-webpack-plugin‘);

  module.exports = {
    entry: {
      main: ‘./src/index.js‘,
      vendor: [
        ‘lodash‘
      ]
    },
    plugins: [
      new CleanWebpackPlugin([‘dist‘]),
      new HtmlWebpackPlugin({
        title: ‘Caching‘
      }),
+     new webpack.HashedModuleIdsPlugin(),
      new webpack.optimize.CommonsChunkPlugin({
        name: ‘vendor‘
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: ‘runtime‘
      })
    ],
    output: {
      filename: ‘[name].[contenthash].js‘,
      path: path.resolve(__dirname, ‘dist‘)
    }
  };

现在,不管再添加任何新的本地依赖,对于每次构建,vendor hash 都应该保持一致:

Hash: 1f49b42afb9a5acfbaff
Version: webpack 3.3.0
Time: 1372ms
                          Asset       Size  Chunks                    Chunk Names
 vendor.eed6dcc3b30cfa138aaa.js     541 kB       0  [emitted]  [big]  vendor
   main.d103ac311788fcb7e329.js    1.22 kB       1  [emitted]         main
runtime.d2a6dc1ccece13f5a164.js    5.85 kB       2  [emitted]         runtime
                     index.html  352 bytes          [emitted]
[3Di9] ./src/print.js 62 bytes {1} [built]
[3IRH] (webpack)/buildin/module.js 517 bytes {0} [built]
[DuR2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [0] multi lodash 28 bytes {0} [built]
[lVK7] ./src/index.js 421 bytes {1} [built]
    + 1 hidden module

然后,修改我们的 src/index.js,临时移除额外的依赖:

src/index.js

  import _ from ‘lodash‘;
- import Print from ‘./print‘;
+ // import Print from ‘./print‘;

  function component() {
    var element = document.createElement(‘div‘);

    // lodash 是由当前 script 脚本 import 导入进来的
    element.innerHTML = _.join([‘Hello‘, ‘webpack‘], ‘ ‘);
-   element.onClick = Print.bind(null, ‘Hello webpack!‘);
+   // element.onClick = Print.bind(null, ‘Hello webpack!‘);

    return element;
  }

  document.body.appendChild(component());

最后,再次运行我们的构建:

Hash: 37e1358f135c0b992f72
Version: webpack 3.3.0
Time: 1557ms
                          Asset       Size  Chunks                    Chunk Names
 vendor.eed6dcc3b30cfa138aaa.js     541 kB       0  [emitted]  [big]  vendor
   main.fc7f38e648da79db2aba.js  891 bytes       1  [emitted]         main
runtime.bb5820632fb66c3fb357.js    5.85 kB       2  [emitted]         runtime
                     index.html  352 bytes          [emitted]
[3IRH] (webpack)/buildin/module.js 517 bytes {0} [built]
[DuR2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [0] multi lodash 28 bytes {0} [built]
[lVK7] ./src/index.js 427 bytes {1} [built]
    + 1 hidden module

我们可以看到,这两次构建中,vendor bundle 的文件名称,都是 eed6dcc3b30cfa138aaa

原文地址:https://www.cnblogs.com/chris-oil/p/8424384.html

时间: 2024-08-30 13:11:47

webpack 模块标识符(Module Identifiers)的相关文章

webpack模块机制浅析【一】

webpack模块机制浅析[一] 今天看了看webpack打包后的代码,所以就去分析了下代码的运行机制. 下面这段代码是webpack打包后的最基本的形式,可以说是[骨架] (function(root,fn){ if(typeof exports ==='object'&&typeof module === 'object'){ module.exports = fn();//exports和module同时存在,说明时在node的CommonJs规范下,这个时候使用module.exp

webpack的Hot Module Replacement运行机制

使用webpack打包,难免会使用Hot Module Replacement功能,该功能能够实现修改.添加或删除前端页面中的模块代码,而且是在页面不刷新的前提下.它究竟是怎么运作的呢?本文主要从调试工具.配置文件.官方文档三个方面进行解析. 调试工具 首先从chrome的调试工具network中看看,代码改变的时候,页面与后端之间发生了什么? 页面初始加载 我们看到除了加载页面所依赖的文件外,多了一个连接,这是一个Server-sent Events,相关的介绍可以参考这篇文章,而且每隔一段时

webpack模块依赖管理介绍

http://webpack.github.io/docs/ webpack is a module bundler. 是一个模块管理器 webpack可以管理模块的依赖关系,并产生可以替代这些模块的静态代码 已有方案 V.S. Webpack <script>: <script src="module1.js"></script> <script src="module2.js"></script> &l

JavaScript系列文章:React总结之Webpack模块组织

现代前端开发离不开打包工具,以Webpack为代表的打包工具已经成为日常开发必备的工具,以React技术栈为例,我们ES6形式的源代码,需要经过Webpack和Babel处理,才能生成发布版文件,在浏览器中运行.今天就结合React来梳理一下Webpack打包时模块的组织结构,先给定下面一个简单的应用示例: import React from 'react'; import ReactDOM from 'react-dom'; import {greet} from './utils'; con

Webpack &amp; The Hot Module Replacement热模块替换原理解析

Webpack & The Hot Module Replacement热模块替换原理解析 The Hot Module Replacement(HMR)俗称热模块替换.主要用来当代码产生变化后,可以在不刷新游览器的情况下对局部代码块进行替换更新.这在很多情况下都很有用,例如在处理弹出框时,使用HMR可以及时的看到变化,如果用刷新游览器的方式会回到初始页面. 很多人使用过HMR却不知道它是如何工作的,这里会对HMR实现原理进行解析. 关于HMR需要知道的一些事 HMR是Webpack的一个可选功

webpack里的module选项配置

webpack里的module 有loaders选项和noParse选项,noParse选项配置不需要解析的目录和文件 module:{ loaders:[], noParse: [ path.join(__dirname + '/client/node_modules/jquery/'), path.join(__dirname + '/client/lib/**') ] }

service_identity 模块 AttributeError: &#39;module&#39; object has no attribute &#39;Any&#39;

安装scrapy之后,开始第一步创建scrapy的工程,之后提示一个userwarning:提示我service_identity没有安装,我通过pip install service_identity安装之后,重新创建一个scrapy的爬虫工程有提示以下的错误. Traceback (most recent call last): File "/usr/local/bin/scrapy", line 4, in execute() File "/usr/local/lib/

webpack:Cannot find module &#39;extract-text-webpack-plugin&#39;

问题: 在终端中使用此命令安装了extract-text-webpack-plugin,npm install -g extract-text-webpack-plugin并在webpack.config.js文件中导入,但是运行终端npm run build后,仍然收到错误显示:Cannot find module 'extract-text-webpack-plugin'. 原因: extract-text-webpack-plugi不是全局安装 解决方法: 1.添加-g标志来安装packa

(转)关于ES6的 模块功能 Module 中export import的用法和注意之处

关于ES6的 模块功能 Module 中export import的用法和注意之处 export default 的用法 export default命令用于指定模块的默认输出.显然,一个模块只能有一个默认输出,因此export deault命令只能使用一次.所以,import命令后面才不用加大括号,相反其它的export 输出 可以有多个,且import时必须加大括号,示例如下: 1 // modules.js 2 function add(x, y) { 3 return x * y; 4