webpack:系统的了解webpack一些核心概念

webpack 如何处理应用程序?

从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块(chunk)组合成一个或多个 bundles

何为webpack模块chunk?

  • ES2015 import 语句
  • CommonJS require() 语句
  • AMD define 和 require 语句
  • css/sass/less 文件中的 @import 语句。
  • stylesheet url(…) 或者 HTML <img src=...> 文件中的图片链接。

可以被这些引用的都算一个模块 chunk

Webpack 天生支持如下模块类型:

  • ECMAScript 模块
  • CommonJS 模块
  • AMD 模块
  • Assets
  • WebAssembly 模块

当遇到不支持的,可以编写 loader 使其支持。也就是说通过 loader 可以使 webpack 支持多种语言和预处理器语法编写的模块。
比如:

入口(entry)

入口默认是 ./src/index.js,可以在 entry 配置

输出(output)

默认值是 ./dist/main.js

loader

webpack 默认只能理解 JavaScript 和 JSON 文件,当需要处理其他文件时可以用loader。

在 webpack 的配置中,loader 有两个属性:

  • test 属性,识别出哪些文件会被转换。
  • use 属性,定义出在进行转换时,应该使用哪个 loader。
// webpack 编译器,当你碰到「在 require()/import 语句中被解析为 '.txt' 的路径」时,在你对它打包之前,先 use(使用) raw-loader 转换一下。
module.exports = {
    
    
  module: {
    
    
    rules: [{
    
     test: /\.txt$/, use: 'raw-loader' }],
  },
};

loader 支持链式调用,数组里的 loader 反向执行从后往前,将其结果(也就是应用过转换后的资源)传递给下一个 loader。

开发loader
module.exports = function (content) {
    
    
  console.log(content);
  return content + '123';
};

插件(plugin)

简介

loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。

const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // 用于访问内置插件

module.exports = {
    
    
  module: {
    
    
    rules: [{
    
     test: /\.txt$/, use: 'raw-loader' }],
  },
  plugins: [new HtmlWebpackPlugin({
    
     template: './src/index.html' })],
};

示例中,html-webpack-plugin 为应用程序生成一个 HTML 文件,并自动将生成的所有 bundle 注入到此文件中。

流程

webpack 的整体流程可以分为 env > init > compiler > make > seal > emit > done

env 和 init 阶段负责初始化环境和激活 webpack 内部插件
compiler 阶段是编译的开始
make 阶段 webpack 会进行依赖分析和收集
seal 阶段 webpack 会生成 chunk 文件
emit 阶段 webpack 会把 chunks 写入硬盘
done 阶段,顾名思义就会 webpack 工作完成啦

插件开发:

https://webpack.docschina.org/api/plugins

Compiler 模块是 webpack 的主要引擎,它通过 CLI 或者 Node API 传递的所有选项创建出一个 compilation 实例。 它扩展(extends)自 Tapable 类,用来注册和调用插件。 大多数面向用户的插件会首先在 Compiler 上注册。https://webpack.docschina.org/api/compiler-hooks/#hooks

Tapable类

这个小型库是 webpack 的一个核心工具,提供类似的插件接口,也是一个 npm 包。有点像一个发布订阅的工具。

在 webpack 中的许多对象都扩展自 Tapable 类。 它对外暴露了 tap,tapAsync 和 tapPromise 等方法, 插件可以使用这些方法向 webpack 中注入自定义构建的步骤

https://github.com/webpack/tapable

监听(watching)

监听时,compiler 会触发诸如 watchRun, watchClose 和 invalid 等额外的事件。 通常在 开发环境 中使用, 也常常会在 webpack-dev-server 这些工具的底层调用, 由此开发人员无须每次都使用手动方式重新编译。

compiler 钩子

以下生命周期钩子函数,是由 compiler 暴露

compiler.hooks.someHook.tap('MyPlugin', (params) => {
    
    
  /* ... */
});

tap 不止是 tap,也可以在某些钩子上访问 tapAsync 和 tapPromise,具体看Tapable。

someHook 可以是以下钩子函数:
1、environment:在编译器准备环境时调用,时机就在配置文件中初始化插件之后。
2、afterEnvironment:当编译器环境设置完成后,在 environment hook 后直接调用。
3、entryOption:在 webpack 选项中的 entry 被处理过之后调用。

compiler.hooks.entryOption.tap('MyPlugin', (context, entry) => {
    
    
  /* ... */
});

4、afterPlugins:在初始化内部插件集合完成设置之后调用。
5、initialize:当编译器对象被初始化时调用。
6、beforeRun:在开始执行一次构建之前调用,compiler.run 方法开始执行后立刻进行调用。
7、run:在开始读取 records 之前调用。
8、watchRun:在监听模式下,一个新的 compilation 触发之后,但在 compilation 实际开始之前执行。
9、compile:beforeCompile 之后立即调用,但在一个新的 compilation 创建之前。这个钩子 不会 被复制到子编译器。
10、compilation:compilation 创建之后执行。
11、emit:输出 asset 到 output 目录之前执行。这个钩子 不会 被复制到子编译器。
12、done:在 compilation 完成时执行。这个钩子 不会 被复制到子编译器。
13、failed:在 compilation 失败时调用。
14、shutdown:当编译器关闭时调用。

完整钩子:https://webpack.docschina.org/api/compiler-hooks/#hooks

compilation 钩子

compiler 创建的 compilation 实例。在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)。

钩子函数:
1、buildModule:在模块构建开始之前触发,可以用来修改模块。

compilation.hooks.buildModule.tap(
  'SourceMapDevToolModuleOptionsPlugin',
  (module) => {
    
    
    module.useSourceMap = true;
  }
);

2、succeedModule:模块构建成功时执行。
3、optimize:优化阶段开始时触发。
4、optimizeChunks:在 chunk 优化阶段开始时调用。插件可以 tap 此钩子对 chunk 执行优化。

完整钩子:https://webpack.docschina.org/api/compilation-hooks/

compiler和compilation

Compiler 和 Compilation 的区别在于:Compiler 代表了整个 Webpack 从启动到关闭的生命周期,而 Compilation 只是代表了一次新的编译。

webpack 编译会创建两个核心对象:

  • compiler :包含了 webpack 环境所有的 配置信息,包括了 options,loader,plugin,和 webpack 整个生命周期有关的钩子。

  • compilation: 作为 plugin 内置事件回调函数的参数,包含了当前的 模块资源,编译生成资源,变化的文件 以及 被 跟踪的文件 的状态信息,当检测到了一个文件发生了改变的时候,就会生成一个新的 Compilation 对象。

  • Compiler 对象包含了 Webpack 环境所有的的配置信息,包含 options,loaders,plugins 这些信息,这个对象在 Webpack 启动时候被实例化,它是全局唯一的,可以简单地把它理解为 Webpack 实例;

  • Compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。当 Webpack 以开发模式运行时,每当检测到一个文件变化,一次新的 Compilation 将被创建。Compilation 对象也提供了很多事件回调供插件做扩展。通过 Compilation 也能读取到 Compiler 对象。

创建自定义 插件
  • 插件必须是一个函数或者是一个包含了 apply 方法的对象,这样才能够访问 Compiler 对象。

  • 传给每一个插件的 compiler 和 compilation 对象都是同一个应用,因此不建议修改。

  • 异步的事件需要在插件处理完任务和调用回调函数通知 webpack 进入下一个流程,不然会卡住。

class MyPlugin {
    
    
    // Webpack 会调用 MyPlugin 实例的 apply 方法给插件实例传入 compiler 对象
  apply (compiler) {
    
    
    // 找到合适的事件钩子,实现自己的插件功能
    compiler.hooks.emit.tap('MyPlugin', compilation => {
    
    
        // compilation: 当前打包构建流程的上下文
        console.log(compilation);
        
        // do something...
    })
  }
}

在 emit 事件发生的时候,代表源文件的转换和组装已经完成,可以读取到最终将输出的 资源,代码块,模块,依赖,并且可以修改输出资源的内容。

loader和plugins区别

  • loader运行在项目打包之前;
  • plugins运行在整个项目的编译时期;

loader 即为文件加载器,操作的是文件,将文件A通过loader转换成文件B,是一个单纯的文件转化过程。比如将 A.less 转换成 B.css

plugins 基于事件机制工作,监听webpack打包过程中的某些节点,执行广泛的任务。

模式(mode)

通过选择 development, production 或 none 之中的一个

插件覆写文件

以下是一个简单的示例,这个插件会在Webpack处理文件时,将所有的JavaScript代码转换为CoffeeScript代码:

const Tapable = require('tapable');  
const coffee = require('coffee-script');  
  
class CoffeeScriptPlugin {
    
      
  constructor(options) {
    
      
    this.options = options || {
    
    };  
  }  
  
  apply(compiler) {
    
      
    compiler.hooks.emit.tapAsync('CoffeeScriptPlugin', (compilation, callback) => {
    
      
      Object.keys(compilation.assets).forEach((data) => {
    
      
        if (/\.js$/.test(data)) {
    
      
          const content = compilation.assets[data].source();  
          const coffeeScript = coffee.compile(content, {
    
    bare: true});  
          compilation.assets[data] = {
    
      
            source: () => coffeeScript,  
            size: () => coffeeScript.length,  
          };  
        }  
      });  
      callback();  
    });  
  }  
}  
  
module.exports = CoffeeScriptPlugin;

在这个示例中,我们首先创建了一个新的类CoffeeScriptPlugin,这个类继承自Tapable。然后,我们在apply方法中注册了一个在emit阶段执行的钩子函数。在这个钩子函数中,我们遍历了所有的资源,如果资源的名字以.js结尾,我们就用CoffeeScript编译这个资源的内容,然后用编译后的内容替换原来的内容。最后,我们调用callback函数来通知Webpack继续执行下一个阶段的任务。

一个项目同时使用多个webpack插件,插件的执行顺序是怎么样的

Webpack的插件系统是基于Tapable库实现的,该库为插件提供了可插拔的接口。因此,具体的插件执行顺序取决于Webpack事件流中的插件注册顺序以及触发时机。

插件通常在Webpack的配置文件(即webpack.config.js文件)中按照数组的形式进行声明。数组中的插件按照先后顺序执行。例如:

module.exports = {
    
      
  //...  
  plugins: [  
    new HtmlWebpackPlugin(),  
    new CleanWebpackPlugin(),  
    //...  
  ],  
};

在上面的示例中,首先执行HtmlWebpackPlugin插件,然后执行CleanWebpackPlugin插件。

然而,这只是一部分真相。Webpack的编译过程中存在许多生命周期钩子,例如’compilation’, ‘optimize’, ‘emit’,等等。插件可能会绑定到一个或多个钩子上。这意味着插件的执行可能会分布在Webpack的整个编译周期中,取决于它们选择“绑定”的那些钩子。

如果两个插件绑定到同一个钩子,那么在webpack.config.js中先声明的插件将先执行。然而,如果一个插件绑定到了早期的钩子(例如’compilation’),而另一个插件绑定到了较晚的钩子(例如’emit’),那么即使在webpack.config.js中后声明的插件也将先执行,因为’compilation’阶段在’emit’阶段之前。

综上,Webpack插件的执行顺序主要取决于两个因素:它们在webpack.config.js文件中的声明顺序,以及它们绑定的钩子在Webpack编译周期中的触发顺序。

常用配置

/* 未使用脚手架打包 
  //开发环境
  webpack '输入文件' -o '输出文件' --mode=development
  //生产环境
  webpack '输入文件' -o '输出文件' --mode=production      
*/
 
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')
const TerserWebpackPlugin = require('terser-webpack-plugin')
const webpack = require('webpack')
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
 
/* 
  ## 懒加载
  ## import动态导入能将导入的文件单独打包,跟多入口文件效果类似
  webpackChunkName: 'test'
  import('./test')
    .then(res => {
      // 成功引入后执行的步骤
    })
    .catch(err => {
      console.log('文件加载失败~')
    })
*/
 
  // ## 预加载
  // import(/* webpackChunkName: 'test', webpackPrefetch: true */'./test').then()
  // ## 懒加载
  // import(/* webpackChunkName: 'test' */'./test').then()
 
module.exports = {
    
    
  // 单入口打包(打包成一个chunk)
  entry: './src/index.js',
  /*
  另外的写法:
    // 单文件入口(打包成一个chunk),add.js加到index.js上,仅用于HMR HTML文件热更新
    entry: ['./src.index.js', './src/add.js'],
    // 多入口打包(打包成多个chunk,也可以进行代码分割)
    entry: {
      index: './src.index.js',
      add: './src/add.js'
    },
    // 多入口加文件合并(打包成多个chunk)
    entry: {
      index: ['./src.index.js', './src/count.js'],
      add: './src/add.js'
    },
  */
 
  output: {
    
    
    // 文件名称(指定名称+目录)
    /* 
      ## hash 每次打包都会生成一个唯一的hash值
      ## chunkhash: 根据输出的不同的chunk生成不同的chunk值,
      ## contenthash: 根据 不同的文件生成不同的hash值(推荐)
    */
    filename: 'js/[name].[contenthash: 8].js',
    // 输出所有文件的公共目录
    path: resolve(__dirname, 'build'),
    // 所有资源的引入公共路径前缀,相当于跨域中的前缀
    publicPath: '/',
    // 非入口chunk的名称,不设置都会走filename的方式命名,例如import('../xxx.js')导入的文件
    chunkFilename: '[name]_chunk.js',
    // 打包后要引用其中的文件,通过library暴露一个对象,达到调用的目的,一般结合dll使用
    library: '[name]',
    // 暴露的对象名添加到哪个地方去,window/global/commomjs
    libraryTarget: 'window'
  },
 
  module: {
    
    
    rules: [
      /* 检查js文件格式 */
      {
    
    
        // 在package.json中配置eslintConfig
        test: /\.js$/,
        include: resolve(__dirname, 'src'),
        exclude: /node_modules/,
        // 多个loader
        loader: 'eslint-loader',
        // 优先执行
        enforce: 'pre',
        // 具体的配置选项
        options: {
    
    
          // 自动修复
          fix: true,
          // 指定错误报告的格式规范
          formatter: require('eslint-friendly-formatter')
        }
      },
      /* 处理HTML文件中引入的图片 */
      {
    
    
        test: /\.html$/,
        include: resolve(__dirname, 'src'),
        exclude: /node_modules/,
        loader: 'html-withimg-loader',
 
      },
      /* 打包图片和其他资源 */
      {
    
    
        exclude: /\.(css|html|js|json)$/,
        loader: 'file-loader',
        options: {
    
    
          name: '[hash: 10].[ext]',
          outputPath: 'static/media/'
        }
      },
      {
    
    
        // 以下配置对每个检查的文件只会生效一个
        oneOf: [
          /* 打包图片资源 */
          {
    
    
            test: /\.(jpg|png|gif|bmp|jpeg)$/,
            include: resolve(__dirname, 'src'),
            exclude: /node_modules/,
            loader: 'url-loader',
            options: {
    
    
              // 图片大小限制,小于8kb使用base64处理
              limit: 8 * 1024,
              // 关闭url-loader es6模块化,使用commonJs解析
              esModule: false,
              // 图片重命名
              name: '[hash: 10].[ext]',
              // 指定打包输出路径
              outputPath: 'static/imgs/'
            }
          },
          /* 打包css资源 */
          {
    
    
            test: /\.css$/,
            // 指定检查的文件路径
            include: resolve(__dirname, 'src'),
            // 排除不需要检查的文件路径
            exclude: /node_modules/,
            // 多个loader
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
              // css兼容性处理,配合package.json中的browswerlist使用
              {
    
    
                loader: 'postcss-loader',
                options: {
    
    
                  execute: true,
                  postcssOptions: {
    
    
                    plugins: [
                      [
                        'postcss-preset-env'
                      ]
                    ]
                  }
                }
              }
            ]
          },
          {
    
    
            test: /\.less$/,
            // 指定检查的文件路径
            include: resolve(__dirname, 'src'),
            // 排除不需要检查的文件路径
            exclude: /node_modules/,
            // 多个loader
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
              // css兼容性处理
              {
    
    
                loader: 'postcss-loader',
                options: {
    
    
                  execute: true,
                  postcssOptions: {
    
    
                    plugins: [
                      [
                        'postcss-preset-env'
                      ]
                    ]
                  }
                }
              },
              'less-loader'
            ]
          },
          {
    
    
            test: /\.scss$/,
            // 指定检查的文件路径
            include: resolve(__dirname, 'src'),
            // 排除不需要检查的文件路径
            exclude: /node_modules/,
            // 多个loader
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
              // css兼容性处理
              {
    
    
                loader: 'postcss-loader',
                options: {
    
    
                  execute: true,
                  postcssOptions: {
    
    
                    plugins: [
                      [
                        'postcss-preset-env'
                      ]
                    ]
                  }
                }
              },
              'sass-loader'
            ]
          },
          /* js兼容性处理 */
          {
    
    
            test: /\.js$/,
            include: resolve(__dirname, 'src'),
            exclude: /node_modules/,
            use: [
              /* 
                开启多进程打包
                多进程需启动(约600ms),只有打包时间长的时候适用
                {
                  loader: 'thread-loader',
                  options: {
                    workers: 2  //开启进程2个
                  }
                }
               */
              'thread-loader',
              {
    
    
                loader: 'babel-loader',
                options: {
    
    
                  presets: [
                    [
                      '@babel/preset-env',
                      {
    
    
                        // 按需加载
                        useBuiltIns: "usage", // or "entry"
                        // 指定core-js版本
                        corejs: {
    
    
                          version: 3
                        },
                        // 指定兼容到哪个版本的浏览器
                        targets: {
    
    
                          chrome: '90',
                          firefox: '60',
                          ie: '9'
                        }
                      }
                    ]
                  ],
                  // 开启babel缓存
                  cacheDirectory: true
                }
              }
            ]
          }
        ]
      }
    ]
  },
 
  plugins: [
    /* 创建并复制index.html文件 */
    new HtmlWebpackPlugin({
    
    
      // 引入项目的根HTML文件
      template: './src/index.html',
      minify: {
    
    
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    }),
    /* 抽离css成单独文件 */
    new MiniCssExtractPlugin({
    
    
      filename: 'css/[contenthash: 10].css'
    }),
    /* 压缩css文件 */
    new OptimizeCssAssetsWebpackPlugin(),
    /* 告诉webpack,根据mainfest映射,哪些库不用再打包 */
    new webpack.DllReferencePlugin({
    
    
      manifest: resolve(__dirname, 'dll/mainfest.json')
    }),
    // 配合dll, 引入dll中已经压缩的库
    new AddAssetHtmlWebpackPlugin({
    
    
      filepath: resolve(__dirname, 'dll/jquery.js')
    })
  ],
 
  // 解析模块的规则
  resolve: {
    
    
    // 配置解析模块的路径别名,例如 src别名是@
    alias: {
    
    
      $css: resolve(__dirname, 'src/css'),
      $assets: resolve(__dirname, 'src/assets')
    },
    // 配置省略文件路径的后缀名,文件引入可以省略后缀名
    extensions: ['.js', '.json'],
    // 告诉 webpack 解析模块是去找哪个目录,不配置默认会逐层向上找
    modules: [resolve(__dirname, './node_modules'), 'node_modules']
  },
 
  devServer: {
    
    
    // 运行代码的目录
    contentBase: resolve(__dirname, 'build'),
    // 监视contentBase目录下的所有文件,一旦文件变化就会reload
    watchContentBase: true,
    // 监视配置
    watchOptions: {
    
    
      // 忽略文件
      ignored: /node_modules/
    },
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 8888,
    // 指定域名
    host: 'localhost',
    // 自动打开浏览器
    open: true,
    // 开启HMR功能
    hot: true,
    // 不显示启动服务日志信息
    clientLogLevel: 'none',
    // 除基本启动信息,其他内容不显示
    quiet: true,
    // 如果出错不要全屏提示
    overlay: false,
    // 服务器代理 --> 解决开发环境下跨域问题,与vue相似
    proxy: {
    
    
      // 一旦遇到/api,就转到target这个路径下,并且路径重写,去掉/api
      '/api': {
    
    
        target: 'http://localhost:8080',
        // 路径重写
        pathRewrite: {
    
    
          '^/api': ''
        }
      }
    }
  },
 
  // 将node_modules中的代码单独打包成一个chunk输出,单/多入口都适用
  optimization: {
    
    
    /* 代码分割 */
    splitChunks: {
    
    
      chunks: 'all',
      // 分割的chunk最小为30kb
      minSize: 30 * 1024,
      // 无最大限制
      maxSize: 0,
      // 要提取的chunks最少被引用1次
      minChunks: 1,
      // 按需加载时并行加载的文件的最大数量
      maxAsyncRequests: 5,
      // 入口js文件最大并行请求数量
      maxInitialRequests: 3,
      // 名称连接符
      automaticNameDelimiter: '~',
      // 可以使用命名规则
      name: true,
      // 分割chunk的组
      cacheGroups: {
    
    
        // node_modules文件会被打包到vendors组的chunk中 --> vendors~xxx.js
        // 满足上边的公共规则
        vendors: {
    
    
          test: /[\\/]node_modules[\\/]/,
          // 优先级
          priority: -10
        },
        default: {
    
    
          minChunks: 2,
          priority: -20,
          // 如果当前要打包的模块,和之前已经提取的模块是同一个,就不在重新打包
          reuseExistingChunk: true
        }
      }
    },
    // 将当前模块记录其他模块的hash值单独打包成一个文件,
    // 解决被引用文件修改,hash值改变,引用文件跟着重新打包的问题(缓存失效)
    runtimeChunk: {
    
    
      name: entrypoint => `runtime-${
      
      entrypoint.name}`
    },
    // 配置生产环境的压缩方案: js和css
    minimizer: [
      new TerserWebpackPlugin({
    
    
        // 开启缓存
        cache: true,
        // 开启多进程打包
        parallel: true,
        // 启动source-map
        sourceMap: true
      })
    ]
  },
 
  devtool: source-map,
 
  externals: {
    
    
    // 忽略库名 -- 忽略包名
    jquery: 'jQuery'  // 忽略打包jQuery
  },
  // 指定模式: 开发/生产(production)
  /* 
    ## tree shaking:去除无用代码
    ## 前提: 1. 必须使用ES6模块化    2.开启production环境
    ## package.json中配置"sideEffects": ["*.css","*.less"]   -->不将设置的文件类型tree shaking
  */
  mode: 'development'
}

webpack.dll.js

const {
    
     resolve } = require("path");
const webpack = require('webpack')
/* 
  使用dll技术对某些第三方库进行单独打包
  webpack --config webpack.dll.js
*/
module.exports = {
    
    
  entry: {
    
    
    // 最终打包生成的[name]  -->jquery
    // ['jquery']  --> 要打包的库是jQuery
    jquery: ['jquery']
  },
  output: {
    
    
    filename: '[name].js',
    path: resolve(__dirname, 'dll'),
    library: '[name]_[hash: 8]'
  },
  plugins: [
    // 打包生成一个mainfest.json文件 ,提供与要打包文件的映射关系
    new webpack.DllPlugin({
    
    
      name: '[name]_[hash]', // 映射库的暴露的内容名称
      path: resolve(__dirname, 'dll/mainfest.json') // 输出文件路径
    })
  ]
}

附录:compiler和compilation基本数据结构相同

完整对象:
const a = {
    
    
  _backCompat: true,
  hooks: {
    
    },
  name: undefined,
  startTime: undefined,
  endTime: undefined,
  compiler: {
    
    },
  resolverFactory: {
    
    },
  inputFileSystem: {
    
    },
  fileSystemInfo: {
    
    },
  valueCacheVersions: Map(16) {
    
    
    'webpack/DefinePlugin DC_APP_DOMAIN_MCP' => '"https://xx.xxx.com"',
    ...
  },
  requestShortener: {
    
    },
  compilerPath: '',
  logger: {
    
    
  },
  options: {
    
    },
  outputOptions: {
    
    },
  bail: false,
  profile: false,
  params: {
    
    
    normalModuleFactory: NormalModuleFactory {
    
    
      hooks: [Object],
      resolverFactory: [ResolverFactory],
      ruleSet: [Object],
      context: '/Users/zhangyu/web/yongliu/sub-test-ddd/src',
      fs: [CachedInputFileSystem],
      _globalParserOptions: [Object],
      _globalGeneratorOptions: {
    
    },
      parserCache: [Map],
      generatorCache: [Map],
      _restoredUnsafeCacheEntries: Set(0) {
    
    },
      _parseResourceWithoutFragment: [Function (anonymous)]
    },
    contextModuleFactory: ContextModuleFactory {
    
    
      hooks: [Object],
      resolverFactory: [ResolverFactory]
    }
  },
  mainTemplate: MainTemplate {
    
    },
  chunkTemplate: ChunkTemplate {
    
    },
  runtimeTemplate: RuntimeTemplate {
    
    },
  moduleTemplates: {
    
    },
  moduleMemCaches: undefined,
  moduleMemCaches2: undefined,
  moduleGraph: {
    
    },
  chunkGraph: {
    
    },
  codeGenerationResults: {
    
    },
  processDependenciesQueue: {
    
    },
  addModuleQueue: AsyncQueue {
    
    },
  factorizeQueue: AsyncQueue {
    
    },
  buildQueue: AsyncQueue {
    
    },
  rebuildQueue: AsyncQueue {
    
    },
  creatingModuleDuringBuild: {
    
     },
  entries: Map(9) {
    
    
    'app' => {
    
    
      dependencies: [Array],
      includeDependencies: [],
      options: [Object]
    },
    'pages/index/index' => {
    
    
      dependencies: [Array],
      includeDependencies: [],
      options: [Object]
    },
    'components/loading-page/index' => {
    
    
      dependencies: [Array],
      includeDependencies: [],
      options: [Object]
    },
    'pages/use-chart/index' => {
    
    
      dependencies: [Array],
      includeDependencies: [],
      options: [Object]
    },
    'subpackage-echarts/ec-canvas/ec-canvas' => {
    
    
      dependencies: [Array],
      includeDependencies: [],
      options: [Object]
    },
    'subpackage-echarts/index/index' => {
    
    
      dependencies: [Array],
      includeDependencies: [],
      options: [Object]
    },
    './app.scss__assets_chunk_name__' => {
    
    
      dependencies: [Array],
      includeDependencies: [],
      options: [Object]
    },
    './pages/index/index.scss__assets_chunk_name__' => {
    
    
      dependencies: [Array],
      includeDependencies: [],
      options: [Object]
    },
    './components/loading-page/index.scss__assets_chunk_name__' => {
    
    
      dependencies: [Array],
      includeDependencies: [],
      options: [Object]
    }
  },
  globalEntry: {
    
    
    dependencies: [],
    includeDependencies: [],
    options: {
    
     name: undefined }
  },
  entrypoints: Map(9) {
    
    
    'app' => Entrypoint {
    
    
      groupDebugId: 5000,
      options: [Object],
      _children: [SortableSet [Set]],
      _parents: [SortableSet [Set]],
      _asyncEntrypoints: [SortableSet [Set]],
      _blocks: [SortableSet [Set]],
      chunks: [Array],
      origins: [Array],
      _modulePreOrderIndices: [Map],
      _modulePostOrderIndices: [Map],
      index: 0,
      _runtimeChunk: [Chunk],
      _entrypointChunk: [Chunk],
      _initial: true
    },
    'pages/index/index' => Entrypoint {
    
    
      groupDebugId: 5001,
      options: [Object],
      _children: [SortableSet [Set]],
      _parents: [SortableSet [Set]],
      _asyncEntrypoints: [SortableSet [Set]],
      _blocks: [SortableSet [Set]],
      chunks: [Array],
      origins: [Array],
      _modulePreOrderIndices: [Map],
      _modulePostOrderIndices: [Map],
      index: 1,
      _runtimeChunk: [Chunk],
      _entrypointChunk: [Chunk],
      _initial: true
    }
  },
  asyncEntrypoints: [],
  chunks: Set(8) {
    
    
    Chunk {
    
    
      id: 3,
      ids: [Array],
      debugId: 1000,
      name: 'app',
      idNameHints: [SortableSet [Set]],
      preventIntegration: false,
      filenameTemplate: undefined,
      cssFilenameTemplate: undefined,
      _groups: [SortableSet [Set]],
      runtime: 'runtime',
      files: [SetDeprecatedArray [Set]],
      auxiliaryFiles: Set(0) {
    
    },
      rendered: true,
      hash: '4cdafb006e29619975268c54d16ace97',
      contentHash: [Object: null prototype],
      renderedHash: '4cdafb006e2961997526',
      chunkReason: undefined,
      extraAsync: false
    },
    Chunk {
    
    
      id: 6,
      ids: [Array],
      debugId: 1001,
      name: 'pages/index/index',
      idNameHints: [SortableSet [Set]],
      preventIntegration: false,
      filenameTemplate: undefined,
      cssFilenameTemplate: undefined,
      _groups: [SortableSet [Set]],
      runtime: 'runtime',
      files: [SetDeprecatedArray [Set]],
      auxiliaryFiles: Set(0) {
    
    },
      rendered: true,
      hash: '2df8c7afeffa5b8fa0439233e61f494c',
      contentHash: [Object: null prototype],
      renderedHash: '2df8c7afeffa5b8fa043',
      chunkReason: undefined,
      extraAsync: false
    }
  },
  chunkGroups: [
    Entrypoint {
    
    
      groupDebugId: 5000,
      options: [Object],
      _children: [SortableSet [Set]],
      _parents: [SortableSet [Set]],
      _asyncEntrypoints: [SortableSet [Set]],
      _blocks: [SortableSet [Set]],
      chunks: [Array],
      origins: [Array],
      _modulePreOrderIndices: [Map],
      _modulePostOrderIndices: [Map],
      index: 0,
      _runtimeChunk: [Chunk],
      _entrypointChunk: [Chunk],
      _initial: true
    },
    Entrypoint {
    
    
      groupDebugId: 5001,
      options: [Object],
      _children: [SortableSet [Set]],
      _parents: [SortableSet [Set]],
      _asyncEntrypoints: [SortableSet [Set]],
      _blocks: [SortableSet [Set]],
      chunks: [Array],
      origins: [Array],
      _modulePreOrderIndices: [Map],
      _modulePostOrderIndices: [Map],
      index: 1,
      _runtimeChunk: [Chunk],
      _entrypointChunk: [Chunk],
      _initial: true
    },
  ],
  namedChunkGroups: Map(9) {
    
    },
  namedChunks: Map(11) {
    
    },
  modules: Set(41) {
    
    },
  _modules: Map(41) {
    
    },
  records: {
    
    },
  additionalChunkAssets: [],
  assets: {
    
    
    'app.wxss': RawSource {
    
    
      _valueIsBuffer: true,
      _value: <Buffer >,
      _valueAsBuffer: <Buffer >,
      _valueAsString: undefined
    },
    'pages/index/index.wxss': RawSource {
    
    
      _valueIsBuffer: true,
      _value: <Buffer >,
      _valueAsBuffer: <Buffer >,
      _valueAsString: undefined
    },
    'app.js': CachedSource {
    
    
      _source: [ConcatSource],
      _cachedSourceType: undefined,
      _cachedSource: undefined,
      _cachedBuffer: undefined,
      _cachedSize: undefined,
      _cachedMaps: Map(0) {
    
    },
      _cachedHashUpdate: undefined
    },
    'pages/index/index.js': CachedSource {
    
    
      _source: [ConcatSource],
      _cachedSourceType: undefined,
      _cachedSource: undefined,
      _cachedBuffer: undefined,
      _cachedSize: undefined,
      _cachedMaps: Map(0) {
    
    },
      _cachedHashUpdate: undefined
    },
    'runtime.js': CachedSource {
    
    
      _source: [ConcatSource],
      _cachedSourceType: undefined,
      _cachedSource: undefined,
      _cachedBuffer: undefined,
      _cachedSize: undefined,
      _cachedMaps: Map(0) {
    
    },
      _cachedHashUpdate: undefined
    },
    'common.js': CachedSource {
    
    
      _source: [ConcatSource],
      _cachedSourceType: undefined,
      _cachedSource: undefined,
      _cachedBuffer: undefined,
      _cachedSize: undefined,
      _cachedMaps: Map(0) {
    
    },
      _cachedHashUpdate: undefined
    }
  },
  assetsInfo: Map(27) {
    
    
    'app.wxss' => {
    
     sourceFilename: 'app.scss' },
    'components/loading-page/index.wxss' => {
    
     sourceFilename: 'components/loading-page/index.scss' },
    'pages/index/index.wxss' => {
    
     sourceFilename: 'pages/index/index.scss' },
    'app.js' => {
    
     javascriptModule: false },
    'pages/index/index.js' => {
    
     javascriptModule: false },
    'components/loading-page/index.js' => {
    
     javascriptModule: false },
    'pages/use-chart/index.js' => {
    
     javascriptModule: false },
    'subpackage-echarts/ec-canvas/ec-canvas.js' => {
    
     javascriptModule: false },
    'subpackage-echarts/index/index.js' => {
    
     javascriptModule: false },
    'runtime.js' => {
    
     javascriptModule: false },
    'common.js' => {
    
     javascriptModule: false },
    'app.json' => {
    
     copied: true, sourceFilename: 'app.json' },
    'sitemap.json' => {
    
     copied: true, sourceFilename: 'sitemap.json' },
    'pages/use-chart/index.json' => {
    
     copied: true, sourceFilename: 'pages/use-chart/index.json' },
    'pages/use-chart/index.wxml' => {
    
     copied: true, sourceFilename: 'pages/use-chart/index.wxml' },
    'pages/use-chart/index.wxss' => {
    
     copied: true, sourceFilename: 'pages/use-chart/index.wxss' },
    'pages/index/index.json' => {
    
     copied: true, sourceFilename: 'pages/index/index.json' },
    'pages/index/index.wxml' => {
    
     copied: true, sourceFilename: 'pages/index/index.wxml' },
    'subpackage-echarts/ec-canvas/ec-canvas.json' => {
    
    
      copied: true,
      sourceFilename: 'subpackage-echarts/ec-canvas/ec-canvas.json'
    },
  },
  _assetsRelatedIn: Map(0) {
    
    },
  errors: [],
  warnings: [
  ],
  children: [],
  logging: Map(9) {
    
    
  },
  dependencyFactories: Map(30) {
    
    
  },
  childrenCounters: {
    
    },
  usedChunkIds: null,
  usedModuleIds: null,
  needAdditionalPass: false,
  _restoredUnsafeCacheModuleEntries: Set(0) {
    
    },
  _restoredUnsafeCacheEntries: Map(0) {
    
    },
  builtModules: WeakSet {
    
     <items unknown> },
  codeGeneratedModules: WeakSet {
    
     <items unknown> },
  buildTimeExecutedModules: WeakSet {
    
     <items unknown> },
  _rebuildingModules: Map(0) {
    
    },
  emittedAssets: Set(0) {
    
    },
  comparedForEmitAssets: Set(0) {
    
    },
  fileDependencies: LazySet {
    
    
  },
  contextDependencies: LazySet {
    
    
  },
  missingDependencies: LazySet {
    
    
    
  },
  buildDependencies: LazySet {
    
    
  },
  compilationDependencies: {
    
     add: [Function: deprecated] },
  fullHash: 'af34423fe7957198c3b73910476385cd',
  hash: 'af34423fe7957198c3b7'
}
options对象
{
    
    
    amd: undefined,
    bail: undefined,
    cache: {
    
    
      type: 'filesystem',
      allowCollectingMemory: false,
      maxMemoryGenerations: Infinity,
      maxAge: 5184000000,
      profile: false,
      buildDependencies: [Object],
      cacheDirectory: '/Users/zhangyu/web/yongliu/sub-test-ddd/node_modules/.cache/webpack',
      cacheLocation: '/Users/zhangyu/web/yongliu/sub-test-ddd/node_modules/.cache/webpack/default-none',
      hashAlgorithm: 'md4',
      compression: false,
      idleTimeout: 60000,
      idleTimeoutForInitialStore: 5000,
      idleTimeoutAfterLargeChanges: 1000,
      name: 'default-none',
      store: 'pack',
      version: '',
      memoryCacheUnaffected: false
    },
    context: '/Users/zhangyu/web/yongliu/sub-test-ddd/src',
    dependencies: undefined,
    devServer: undefined,
    devtool: false,
    entry: {
    
     main: [Object] },
    experiments: {
    
    
      buildHttp: undefined,
      lazyCompilation: undefined,
      css: undefined,
      futureDefaults: false,
      backCompat: true,
      topLevelAwait: false,
      syncWebAssembly: false,
      asyncWebAssembly: false,
      outputModule: false,
      layers: false,
      cacheUnaffected: false
    },
    externals: undefined,
    externalsPresets: {
    
    
      web: true,
      node: false,
      nwjs: false,
      electron: false,
      electronMain: false,
      electronPreload: false,
      electronRenderer: false
    },
    externalsType: 'var',
    ignoreWarnings: undefined,
    infrastructureLogging: {
    
    
      stream: [WriteStream],
      level: 'info',
      debug: false,
      colors: true,
      appendOnly: false
    },
    loader: {
    
     target: 'web' },
    mode: 'none',
    module: {
    
    
      noParse: undefined,
      unsafeCache: [Function (anonymous)],
      parser: [Object],
      generator: {
    
    },
      defaultRules: [Array],
      rules: [Array]
    },
    name: undefined,
    node: {
    
     global: true, __filename: 'mock', __dirname: 'mock' },
    optimization: {
    
    
      splitChunks: [Object],
      runtimeChunk: [Object],
      emitOnErrors: true,
      removeAvailableModules: false,
      removeEmptyChunks: true,
      mergeDuplicateChunks: true,
      flagIncludedChunks: false,
      moduleIds: 'natural',
      chunkIds: 'natural',
      sideEffects: 'flag',
      providedExports: true,
      usedExports: false,
      innerGraph: false,
      mangleExports: false,
      concatenateModules: false,
      checkWasmTypes: false,
      mangleWasmImports: false,
      portableRecords: false,
      realContentHash: false,
      minimize: false,
      minimizer: [Array],
      nodeEnv: false
    },
    output: {
    
    
      assetModuleFilename: '[hash][ext][query]',
      asyncChunks: true,
      charset: true,
      chunkFilename: '[name].js',
      chunkFormat: 'array-push',
      chunkLoading: 'jsonp',
      chunkLoadingGlobal: 'webpackChunk',
      chunkLoadTimeout: 120000,
      cssFilename: '[name].css',
      cssChunkFilename: '[name].css',
      clean: undefined,
      compareBeforeEmit: true,
      crossOriginLoading: false,
      devtoolFallbackModuleFilenameTemplate: undefined,
      devtoolModuleFilenameTemplate: undefined,
      devtoolNamespace: '',
      environment: [Object],
      enabledChunkLoadingTypes: [Array],
      enabledLibraryTypes: [],
      enabledWasmLoadingTypes: [Array],
      filename: '[name].js',
      globalObject: 'wx',
      hashDigest: 'hex',
      hashDigestLength: 20,
      hashFunction: 'md4',
      hashSalt: undefined,
      hotUpdateChunkFilename: '[id].[fullhash].hot-update.js',
      hotUpdateGlobal: 'webpackHotUpdate',
      hotUpdateMainFilename: '[runtime].[fullhash].hot-update.json',
      iife: true,
      importFunctionName: 'import',
      importMetaName: 'import.meta',
      scriptType: false,
      library: undefined,
      module: false,
      path: '/Users/zhangyu/web/yongliu/sub-test-ddd/weapp',
      pathinfo: false,
      publicPath: '/Users/zhangyu/web/yongliu/sub-test-ddd/weapp',
      sourceMapFilename: '[file].map[query]',
      sourcePrefix: undefined,
      strictModuleExceptionHandling: false,
      trustedTypes: undefined,
      uniqueName: '',
      wasmLoading: 'fetch',
      webassemblyModuleFilename: '[hash].module.wasm',
      workerChunkLoading: 'import-scripts',
      workerWasmLoading: 'fetch'
    },
    parallelism: 100,
    performance: false,
    plugins: [
      [CLIPlugin],
      [CleanWebpackPlugin],
      [CopyPlugin],
      [MinaWebpackPlugin],
      MinaRuntimeWebpackPlugin {
    
    },
      [DefinePlugin]
    ],
    profile: false,
    recordsInputPath: false,
    recordsOutputPath: false,
    resolve: {
    
    
      byDependency: [Object],
      cache: true,
      modules: [Array],
      conditionNames: [Array],
      mainFiles: [Array],
      extensions: [Array],
      aliasFields: [],
      exportsFields: [Array],
      roots: [Array],
      mainFields: [Array],
      alias: [Object]
    },
    resolveLoader: {
    
    
      cache: true,
      conditionNames: [Array],
      exportsFields: [Array],
      mainFields: [Array],
      extensions: [Array],
      mainFiles: [Array]
    },
    snapshot: {
    
    
      resolveBuildDependencies: [Object],
      buildDependencies: [Object],
      resolve: [Object],
      module: [Object],
      immutablePaths: [],
      managedPaths: [Array]
    },
    stats: {
    
     preset: 'normal', colors: true },
    target: 'web',
    watch: true,
    watchOptions: {
    
    }
  }
outputOptions
{
    
    
    assetModuleFilename: '[hash][ext][query]',
    asyncChunks: true,
    charset: true,
    chunkFilename: '[name].js',
    chunkFormat: 'array-push',
    chunkLoading: 'jsonp',
    chunkLoadingGlobal: 'webpackChunk',
    chunkLoadTimeout: 120000,
    cssFilename: '[name].css',
    cssChunkFilename: '[name].css',
    clean: undefined,
    compareBeforeEmit: true,
    crossOriginLoading: false,
    devtoolFallbackModuleFilenameTemplate: undefined,
    devtoolModuleFilenameTemplate: undefined,
    devtoolNamespace: '',
    environment: {
    
    
      arrowFunction: true,
      const: true,
      destructuring: true,
      forOf: true,
      bigIntLiteral: undefined,
      dynamicImport: undefined,
      module: undefined
    },
    enabledChunkLoadingTypes: [ 'jsonp', 'import-scripts' ],
    enabledLibraryTypes: [],
    enabledWasmLoadingTypes: [ 'fetch' ],
    filename: '[name].js',
    globalObject: 'wx',
    hashDigest: 'hex',
    hashDigestLength: 20,
    hashFunction: 'md4',
    hashSalt: undefined,
    hotUpdateChunkFilename: '[id].[fullhash].hot-update.js',
    hotUpdateGlobal: 'webpackHotUpdate',
    hotUpdateMainFilename: '[runtime].[fullhash].hot-update.json',
    iife: true,
    importFunctionName: 'import',
    importMetaName: 'import.meta',
    scriptType: false,
    library: undefined,
    module: false,
    path: '/Users/zhangyu/web/yongliu/sub-test-ddd/weapp',
    pathinfo: false,
    publicPath: '/Users/zhangyu/web/yongliu/sub-test-ddd/weapp',
    sourceMapFilename: '[file].map[query]',
    sourcePrefix: undefined,
    strictModuleExceptionHandling: false,
    trustedTypes: undefined,
    uniqueName: '',
    wasmLoading: 'fetch',
    webassemblyModuleFilename: '[hash].module.wasm',
    workerChunkLoading: 'import-scripts',
    workerWasmLoading: 'fetch'
  }

猜你喜欢

转载自blog.csdn.net/weixin_43972437/article/details/132855948