Webpack4.x的四个核心概念是什么?

2026-04-02 21:241阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计4358个文字,预计阅读时间需要18分钟。

Webpack4.x的四个核心概念是什么?

目录一. 概念

1.入口

1.1 基础概念 1.2 单文件入口 1.3 多文件入口

2.输出

2.1 基础概念 2.2 使用占位符为每个文件命名,确保名称唯一 2.3 使用CDN和资源hash

3.Loader

3.1 基础概念 3.2 安装

目录
  • 一. 概念
    • 1. 入口
      • 1.1 基础概念
      • 1.2 单文件入口
      • 1.3 多文件入口
    • 2. 出口
      • 2.1 基础概念
      • 2.2 使用占位符来为每个文件命名,保证名称唯一
      • 2.3 使用CDN和资源hash
    • 3. loader
      • 3.1 基础概念
      • 3.2 安装并使用loader
      • 3.3 使用loader的三种方式
      • 3.4 loader加载顺序
      • 3.5 loader 特性
    • 4. 插件
      • 4.1 基础概念
      • 4.2 核心知识
    • 5. 模式
    • 二. 配置
      • 1. 基本配置
        • 2. 多种配置
          • 2.1 导出为一个函数
          • 2.2 导出为一个 Promise
          • 2.3 导出多个配置对象
        • 3. 使用其他配置语言
          • 3.1 TypeScript
          • 3.2 Babel and JSX
      • 三. 模块
        • 1. 模块介绍
          • 2. 模块解析
            • 3. 解析 loader
              • 4. 缓存
              • 四. 构建目标
                • 1. 用法
                  • 2. 多个 target

                  一. 概念

                  需要理解四个核心概念

                  • 入口(entry)
                  • 输出(output)
                  • loader
                  • 插件(plugins)

                  1. 入口

                  1.1 基础概念

                  指定 webpack 由哪个模块作为项目构建的开始。

                  通过配置entry属性,指定一个或多个起点,默认值./src

                  module.exports = { entry: './path/leo/file.js' };

                  1.2 单文件入口

                  用法:entry: string|Array

                  entry中没有配置入口的文件对象的名称,默认使用的是main名称,输出就是main.js,即:

                  // 默认情况 module.exports = { entry: './path/leo/file.js' }; // 配置单个入口 const config = { entry: { main: './path/leo/file.js' } };

                  可以看出,实际上默认情况只是配置单个入口的简写形式。

                  另外,文件路径我们也可以传入一个数组,就会将多个依赖文件一起注入:

                  const config = { entry: { main: ['./path/leo/file.js', './path/leo/index.js', './path/leo/server.js'] } };

                  Webpack4.x的四个核心概念是什么?

                  1.3 多文件入口

                  用法:entry: {[entryChunkName: string]: string|Array}

                  多个文件完全分离互相独立(每个 bundle 中都有一个 webpack 引导(bootstrap)),常见于只有一个入口的单页面应用。

                  const config = { entry: { app: './src/app.js', vendors: './src/vendors.js' } };

                  2. 出口

                  2.1 基础概念

                  指定 webpack最终输出的文件输出位置和文件名等信息。

                  通过配置output属性,指定输出位置和文件名,默认输出位置为./dist

                  两个属性:

                  • path:输出的目录绝对路径;
                  • filename:输出的文件名称;

                  const path = require('path'); module.exports = { entry: './path/leo/file.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'leo-webpack.bundle.js' } };

                  2.2 使用占位符来为每个文件命名,保证名称唯一

                  output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }

                  2.3 使用CDN和资源hash

                  output: { path: "/home/proj/cdn/assets/[hash]", publicPath: "cdn.example.com/assets/[hash]/" }

                  如果编译时不知道最终文件的 publicPath ,可以留空,并在入口文件中动态设置。或者在入口起点设置 __webpack_public_path__ 来忽略它。

                  __webpack_public_path__ = myRuntimePublicPath

                  3. loader

                  3.1 基础概念

                  让 webpack 能够处理非 JS 文件,在import或 “加载”模块时预处理文件。

                  通过配置 loader 两个属性来实现:

                  • test属性,用来标识出应该被对应的 loader 进行转换的某个或多个文件;
                  • use属性,表示转换时要用哪个 loader;

                  const path = require('path'); const config = { output: { filename: 'leo-webpack.bundle.js' }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' } ] } }; module.exports = config;

                  3.2 安装并使用loader

                  如安装一个css-loaderts-loader使得 webpack 可以加载 CSS 文件,或者将TypeScript转换成JavaScript

                  npm install --save-dev css-loader ts-loader

                  使用:

                  // webpack.config.js module.exports = { module: { rules: [ { test: /\.css$/, use: 'css-loader' }, { test: /\.ts$/, use: 'ts-loader' } ] } };

                  3.3 使用loader的三种方式

                  • 配置(推荐):在 webpack.config.js 文件中指定 loader。

                  指定多个loader:

                  module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true } } ] } ] }

                  • 内联:在每个 import 语句中显式指定 loader。

                  可以在import语句或任何等效于import的方式中指定 loader,使用!将多个 loader 分开,每个部分都是相对于当前目录的解析。

                  import Styles from 'style-loader!css-loader?modules!./styles.css';

                  尽可能使用 module.rules,减少代码量,并且在出错时,更快地调试和定位 loader 中的问题。

                  • CLI:在 shell 命令中指定它们。

                  webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

                  3.4 loader加载顺序

                  loader 会从数组最后一个开始,往前一个一个加载:

                  // webpack.config.js module.exports = { module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, ] } };

                  3.5 loader 特性

                  • loader 支持链式传递。
                  • 能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript。
                  • loader 可以是同步的,也可以是异步的。
                  • loader 运行在 Node.js 中,并且能够执行任何可能的操作。
                  • loader 接收查询参数。用于对 loader 传递配置。
                  • loader 也能够使用 options 对象进行配置。
                  • 除了使用 package.json 常见的 main 属性,还可以将普通的 npm 模块导出为 loader,做法是在 package.json 里定义一个 loader 字段。
                  • 插件(plugin)可以为 loader 带来更多特性。
                  • loader 能够产生额外的任意文件。

                  4. 插件

                  4.1 基础概念

                  让 webpack 能够执行更多任务,从优化和压缩,到重新定义环境中的变量,非常强大。

                  插件目的在于解决 loader 无法实现的其他事。

                  使用时,只需要require它,并添加到plugins数组,通过new实例化即可:

                  const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装 const webpack = require('webpack'); // 用于访问内置插件 const config = { module: { rules: [ { test: /\.txt$/, use: 'raw-loader' } ] }, plugins: [ new HtmlWebpackPlugin({template: './src/index.html'}) ]}; module.exports = config;

                  4.2 核心知识

                  原理剖析:

                  webpack 插件是一个具有apply属性的 JavaScript 对象。apply属性会被webpack compiler调用,并且compiler对象可在整个编译生命周期访问

                  用法:

                  由于插件可以携带参数/选项,你必须在webpack配置中,向plugins属性传入new实例。

                  配置:

                  // webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装 const webpack = require('webpack'); //访问内置的插件 const path = require('path'); const config = { entry: './path/leo/file.js', output: { filename: 'my-first-webpack.bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.(js|jsx)$/, use: 'babel-loader' } ] }, plugins: [ new webpack.optimize.UglifyJsPlugin(), new HtmlWebpackPlugin({template: './src/index.html'}) ] }; module.exports = config;

                  5. 模式

                  通过配置mode参数,指定当前的开发模式,有developmentproduction两个值:

                  module.exports = { mode: 'production' };

                  也可以通过 CLI 参数传递:

                  webpack --mode=production

                  参数描述:

                  选项描述development会将process.env.NODE_ENV的值设为development。启用NamedChunksPlugin和NamedModulesPlugin。production会将process.env.NODE_ENV的值设为production。启用FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和UglifyJsPlugin。

                  记住,只设置 NODE_ENV,则不会自动设置 mode。

                  二. 配置

                  webpack 的配置文件,是导出一个对象的 JavaScript 文件,由 webpack 根据对象定义的属性进行解析。

                  因为 webpack 配置是标准的 Node.js CommonJS 模块,你可以做到以下事情:

                  • 通过require(...)导入其他文件;
                  • 通过require(...)使用npm的工具函数;
                  • 使用 JavaScript 控制流表达式,例如?:操作符;
                  • 对常用值使用常量或变量;
                  • 编写并执行函数来生成部分配置;

                  但应避免以下做法:

                  • 在使用 webpack 命令行接口(CLI)(应该编写自己的命令行接口(CLI),或使用--env)时,访问命令行接口(CLI)参数;
                  • 导出不确定的值(调用 webpack 两次应该产生同样的输出文件);
                  • 编写很长的配置(应该将配置拆分为多个文件);

                  1. 基本配置

                  // webpack.config.js var path = require('path'); module.exports = { mode: 'development', entry: './foo.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'foo.bundle.js' } };

                  2. 多种配置

                  除了到处单个配置对象,我们也可以有一些其他方式:

                  2.1 导出为一个函数

                  我们可能需要同时考虑到开发环境生产环境,在webpack.config.js中实现,我们会有至少两种方式:

                  • 导出一个配置对象来代替;
                  • 导出一个可以传入参数的函数:

                  传入两个参数:环境变量(查看 CLI 文档的环境选项)和 map 对象(argv)参数。

                  module.exports = function(env, argv) { return { mode: env.production ? 'production' : 'development', devtool: env.production ? 'source-maps' : 'eval', plugins: [ new webpack.optimize.UglifyJsPlugin({ compress: argv['optimize-minimize'] // 只有传入 -p 或 --optimize-minimize }) ] }; };

                  2.2 导出为一个 Promise

                  webpack 将运行由配置文件导出的函数,并且等待Promise返回。便于需要异步地加载所需的配置变量。

                  module.exports = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ entry: './app.js', /* ... */ }) }, 5000) }) }

                  2.3 导出多个配置对象

                  我们把导出对象设置成一个数组,webpack 运行时,会将所有配置对象都构建,这对于针对多个构建目标(例如 AMD 和 CommonJS)打包一个 library非常有用。

                  module.exports = [{ output: { filename: './dist-amd.js', libraryTarget: 'amd' }, entry: './app.js', mode: 'production', }, { output: { filename: './dist-commonjs.js', libraryTarget: 'commonjs' }, entry: './app.js', mode: 'production', }]

                  3. 使用其他配置语言

                  webpack 接受以多种编程和数据语言编写的配置文件。支持的文件扩展名列表,可以在node-interpret包中找到。使用node-interpret,webpack 可以处理许多不同类型的配置文件。

                  文档介绍:《使用不同语言进行配置(configuration languages)》

                  3.1 TypeScript

                  为了用 TypeScript 书写 webpack 的配置文件,必须先安装相关依赖:

                  npm install --save-dev typescript ts-node @types/node @types/webpack

                  使用 TypeScript 书写 webpack 的配置文件:

                  // webpack.config.ts import path from 'path'; import webpack from 'webpack'; const config: webpack.Configuration = { mode: 'production', entry: './foo.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'foo.bundle.js' } }; export default config;

                  3.2 Babel and JSX

                  在以下的例子中,使用了JSXReact形式的 javascript)以及Babel来创建JSON形式的 webpack 配置文件:

                  首先安装依赖:

                  npm install --save-dev babel-register jsxobj babel-preset-es2015

                  设置配置:

                  // .babelrc { "presets": [ "es2015" ] } // webpack.config.babel.js import jsxobj from 'jsxobj'; // example of an imported plugin const CustomPlugin = config => ({ ...config, name: 'custom-plugin' }); export default ( );

                  三. 模块

                  1. 模块介绍

                  开发中将程序分解成离散功能块,成为模块。

                  而 webpack 模块能够以各种形式表达他们的依赖关系:

                  • es6:import语句;
                  • CommonJS:require()语句;
                  • AMD:definerequire语句;
                  • css/sass/less文件中的@import语句;
                  • 样式(url(...))或 HTML 文件中的图片链接(image url);

                  查看更多模块方法

                  2. 模块解析

                  使用resolver库来找到模块的绝对路径,帮助 webpack 找到 bundle 中需要引入的模块代码,这些代码包含在每个require/import语句中,在模块打包中,webpack 使用enhanced-resolve来解析文件路径

                  webpack 解析规则:使用enhanced-resolvewebpack支持解析三种文件路径:

                  • 绝对路径:

                  import "/home/me/file"; import "C:\\Users\\me\\file";

                  • 相对路径:

                  import "../src/file1"; import "./file2";

                  • 模块路径:

                  import "module"; import "module/lib/file";

                  模块将在resolve.modules中指定的所有目录中搜索,另外可以使用resolve.alias做初始化模块路径。

                  解析器(resolver)检查路径是否指向文件或目录,如果是指向文件:

                  • 如果有文件拓展名则直接打包;
                  • 否则使用 [resolve.extensions] 选项作为文件扩展名来解析,配置解析器在解析中能够接受哪些扩展名(例如.js,.jsx)。

                  如果是指向文件夹,则按照步骤找到正确拓展名的文件:

                  • 如果文件夹中包含package.json文件,则按照顺序查找resolve.mainFields配置选项中指定的字段。并且package.json中的第一个这样的字段确定文件路径。
                  • 如果不存在package.json文件或者package.json文件中的main字段没有返回一个有效路径,则按照顺序查找resolve.mainFiles配置选项中指定的文件名,看是否能在import/require目录下匹配到一个存在的文件名。
                  • 文件扩展名通过resolve.extensions选项采用类似的方法进行解析。

                  3. 解析 loader

                  Loader 解析遵循与文件解析器指定的规则相同的规则。但是resolveLoader配置选项可以用来为 Loader 提供独立的解析规则。

                  4. 缓存

                  每个文件系统访问都被缓存,以便更快触发对同一文件的多个并行或串行请求。在观察模式下,只有修改过的文件会从缓存中摘出。如果关闭观察模式,在每次编译前清理缓存。

                  有关上述配置的更多信息,请查看解析 API学习。

                  四. 构建目标

                  注意:webpack 的target属性不要和output.libraryTarget属性混淆。

                  1. 用法

                  在你的 webpack 配置中设置target的值:

                  module.exports = { target: 'node' };

                  在上面例子中,使用nodewebpack 会编译为用于「类 Node.js」环境(使用 Node.js 的require,而不是使用任意内置模块(如fspath)来加载 chunk)。

                  更多详细的值,可以参考构建目标(targets)

                  2. 多个 target

                  尽管 webpack 不支持向target传入多个字符串,你可以通过打包两份分离的配置来创建同构的库:

                  var path = require('path'); var serverConfig = { target: 'node', output: { path: path.resolve(__dirname, 'dist'), filename: 'lib.node.js' } //… }; var clientConfig = { target: 'web', // <=== 默认是 'web',可省略 output: { path: path.resolve(__dirname, 'dist'), filename: 'lib.js' } //… }; module.exports = [ serverConfig, clientConfig ];

                  到此这篇关于Webpack核心概念的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。

                  本文共计4358个文字,预计阅读时间需要18分钟。

                  Webpack4.x的四个核心概念是什么?

                  目录一. 概念

                  1.入口

                  1.1 基础概念 1.2 单文件入口 1.3 多文件入口

                  2.输出

                  2.1 基础概念 2.2 使用占位符为每个文件命名,确保名称唯一 2.3 使用CDN和资源hash

                  3.Loader

                  3.1 基础概念 3.2 安装

                  目录
                  • 一. 概念
                    • 1. 入口
                      • 1.1 基础概念
                      • 1.2 单文件入口
                      • 1.3 多文件入口
                    • 2. 出口
                      • 2.1 基础概念
                      • 2.2 使用占位符来为每个文件命名,保证名称唯一
                      • 2.3 使用CDN和资源hash
                    • 3. loader
                      • 3.1 基础概念
                      • 3.2 安装并使用loader
                      • 3.3 使用loader的三种方式
                      • 3.4 loader加载顺序
                      • 3.5 loader 特性
                    • 4. 插件
                      • 4.1 基础概念
                      • 4.2 核心知识
                    • 5. 模式
                    • 二. 配置
                      • 1. 基本配置
                        • 2. 多种配置
                          • 2.1 导出为一个函数
                          • 2.2 导出为一个 Promise
                          • 2.3 导出多个配置对象
                        • 3. 使用其他配置语言
                          • 3.1 TypeScript
                          • 3.2 Babel and JSX
                      • 三. 模块
                        • 1. 模块介绍
                          • 2. 模块解析
                            • 3. 解析 loader
                              • 4. 缓存
                              • 四. 构建目标
                                • 1. 用法
                                  • 2. 多个 target

                                  一. 概念

                                  需要理解四个核心概念

                                  • 入口(entry)
                                  • 输出(output)
                                  • loader
                                  • 插件(plugins)

                                  1. 入口

                                  1.1 基础概念

                                  指定 webpack 由哪个模块作为项目构建的开始。

                                  通过配置entry属性,指定一个或多个起点,默认值./src

                                  module.exports = { entry: './path/leo/file.js' };

                                  1.2 单文件入口

                                  用法:entry: string|Array

                                  entry中没有配置入口的文件对象的名称,默认使用的是main名称,输出就是main.js,即:

                                  // 默认情况 module.exports = { entry: './path/leo/file.js' }; // 配置单个入口 const config = { entry: { main: './path/leo/file.js' } };

                                  可以看出,实际上默认情况只是配置单个入口的简写形式。

                                  另外,文件路径我们也可以传入一个数组,就会将多个依赖文件一起注入:

                                  const config = { entry: { main: ['./path/leo/file.js', './path/leo/index.js', './path/leo/server.js'] } };

                                  Webpack4.x的四个核心概念是什么?

                                  1.3 多文件入口

                                  用法:entry: {[entryChunkName: string]: string|Array}

                                  多个文件完全分离互相独立(每个 bundle 中都有一个 webpack 引导(bootstrap)),常见于只有一个入口的单页面应用。

                                  const config = { entry: { app: './src/app.js', vendors: './src/vendors.js' } };

                                  2. 出口

                                  2.1 基础概念

                                  指定 webpack最终输出的文件输出位置和文件名等信息。

                                  通过配置output属性,指定输出位置和文件名,默认输出位置为./dist

                                  两个属性:

                                  • path:输出的目录绝对路径;
                                  • filename:输出的文件名称;

                                  const path = require('path'); module.exports = { entry: './path/leo/file.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'leo-webpack.bundle.js' } };

                                  2.2 使用占位符来为每个文件命名,保证名称唯一

                                  output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }

                                  2.3 使用CDN和资源hash

                                  output: { path: "/home/proj/cdn/assets/[hash]", publicPath: "cdn.example.com/assets/[hash]/" }

                                  如果编译时不知道最终文件的 publicPath ,可以留空,并在入口文件中动态设置。或者在入口起点设置 __webpack_public_path__ 来忽略它。

                                  __webpack_public_path__ = myRuntimePublicPath

                                  3. loader

                                  3.1 基础概念

                                  让 webpack 能够处理非 JS 文件,在import或 “加载”模块时预处理文件。

                                  通过配置 loader 两个属性来实现:

                                  • test属性,用来标识出应该被对应的 loader 进行转换的某个或多个文件;
                                  • use属性,表示转换时要用哪个 loader;

                                  const path = require('path'); const config = { output: { filename: 'leo-webpack.bundle.js' }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' } ] } }; module.exports = config;

                                  3.2 安装并使用loader

                                  如安装一个css-loaderts-loader使得 webpack 可以加载 CSS 文件,或者将TypeScript转换成JavaScript

                                  npm install --save-dev css-loader ts-loader

                                  使用:

                                  // webpack.config.js module.exports = { module: { rules: [ { test: /\.css$/, use: 'css-loader' }, { test: /\.ts$/, use: 'ts-loader' } ] } };

                                  3.3 使用loader的三种方式

                                  • 配置(推荐):在 webpack.config.js 文件中指定 loader。

                                  指定多个loader:

                                  module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true } } ] } ] }

                                  • 内联:在每个 import 语句中显式指定 loader。

                                  可以在import语句或任何等效于import的方式中指定 loader,使用!将多个 loader 分开,每个部分都是相对于当前目录的解析。

                                  import Styles from 'style-loader!css-loader?modules!./styles.css';

                                  尽可能使用 module.rules,减少代码量,并且在出错时,更快地调试和定位 loader 中的问题。

                                  • CLI:在 shell 命令中指定它们。

                                  webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

                                  3.4 loader加载顺序

                                  loader 会从数组最后一个开始,往前一个一个加载:

                                  // webpack.config.js module.exports = { module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, ] } };

                                  3.5 loader 特性

                                  • loader 支持链式传递。
                                  • 能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript。
                                  • loader 可以是同步的,也可以是异步的。
                                  • loader 运行在 Node.js 中,并且能够执行任何可能的操作。
                                  • loader 接收查询参数。用于对 loader 传递配置。
                                  • loader 也能够使用 options 对象进行配置。
                                  • 除了使用 package.json 常见的 main 属性,还可以将普通的 npm 模块导出为 loader,做法是在 package.json 里定义一个 loader 字段。
                                  • 插件(plugin)可以为 loader 带来更多特性。
                                  • loader 能够产生额外的任意文件。

                                  4. 插件

                                  4.1 基础概念

                                  让 webpack 能够执行更多任务,从优化和压缩,到重新定义环境中的变量,非常强大。

                                  插件目的在于解决 loader 无法实现的其他事。

                                  使用时,只需要require它,并添加到plugins数组,通过new实例化即可:

                                  const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装 const webpack = require('webpack'); // 用于访问内置插件 const config = { module: { rules: [ { test: /\.txt$/, use: 'raw-loader' } ] }, plugins: [ new HtmlWebpackPlugin({template: './src/index.html'}) ]}; module.exports = config;

                                  4.2 核心知识

                                  原理剖析:

                                  webpack 插件是一个具有apply属性的 JavaScript 对象。apply属性会被webpack compiler调用,并且compiler对象可在整个编译生命周期访问

                                  用法:

                                  由于插件可以携带参数/选项,你必须在webpack配置中,向plugins属性传入new实例。

                                  配置:

                                  // webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装 const webpack = require('webpack'); //访问内置的插件 const path = require('path'); const config = { entry: './path/leo/file.js', output: { filename: 'my-first-webpack.bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.(js|jsx)$/, use: 'babel-loader' } ] }, plugins: [ new webpack.optimize.UglifyJsPlugin(), new HtmlWebpackPlugin({template: './src/index.html'}) ] }; module.exports = config;

                                  5. 模式

                                  通过配置mode参数,指定当前的开发模式,有developmentproduction两个值:

                                  module.exports = { mode: 'production' };

                                  也可以通过 CLI 参数传递:

                                  webpack --mode=production

                                  参数描述:

                                  选项描述development会将process.env.NODE_ENV的值设为development。启用NamedChunksPlugin和NamedModulesPlugin。production会将process.env.NODE_ENV的值设为production。启用FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和UglifyJsPlugin。

                                  记住,只设置 NODE_ENV,则不会自动设置 mode。

                                  二. 配置

                                  webpack 的配置文件,是导出一个对象的 JavaScript 文件,由 webpack 根据对象定义的属性进行解析。

                                  因为 webpack 配置是标准的 Node.js CommonJS 模块,你可以做到以下事情:

                                  • 通过require(...)导入其他文件;
                                  • 通过require(...)使用npm的工具函数;
                                  • 使用 JavaScript 控制流表达式,例如?:操作符;
                                  • 对常用值使用常量或变量;
                                  • 编写并执行函数来生成部分配置;

                                  但应避免以下做法:

                                  • 在使用 webpack 命令行接口(CLI)(应该编写自己的命令行接口(CLI),或使用--env)时,访问命令行接口(CLI)参数;
                                  • 导出不确定的值(调用 webpack 两次应该产生同样的输出文件);
                                  • 编写很长的配置(应该将配置拆分为多个文件);

                                  1. 基本配置

                                  // webpack.config.js var path = require('path'); module.exports = { mode: 'development', entry: './foo.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'foo.bundle.js' } };

                                  2. 多种配置

                                  除了到处单个配置对象,我们也可以有一些其他方式:

                                  2.1 导出为一个函数

                                  我们可能需要同时考虑到开发环境生产环境,在webpack.config.js中实现,我们会有至少两种方式:

                                  • 导出一个配置对象来代替;
                                  • 导出一个可以传入参数的函数:

                                  传入两个参数:环境变量(查看 CLI 文档的环境选项)和 map 对象(argv)参数。

                                  module.exports = function(env, argv) { return { mode: env.production ? 'production' : 'development', devtool: env.production ? 'source-maps' : 'eval', plugins: [ new webpack.optimize.UglifyJsPlugin({ compress: argv['optimize-minimize'] // 只有传入 -p 或 --optimize-minimize }) ] }; };

                                  2.2 导出为一个 Promise

                                  webpack 将运行由配置文件导出的函数,并且等待Promise返回。便于需要异步地加载所需的配置变量。

                                  module.exports = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ entry: './app.js', /* ... */ }) }, 5000) }) }

                                  2.3 导出多个配置对象

                                  我们把导出对象设置成一个数组,webpack 运行时,会将所有配置对象都构建,这对于针对多个构建目标(例如 AMD 和 CommonJS)打包一个 library非常有用。

                                  module.exports = [{ output: { filename: './dist-amd.js', libraryTarget: 'amd' }, entry: './app.js', mode: 'production', }, { output: { filename: './dist-commonjs.js', libraryTarget: 'commonjs' }, entry: './app.js', mode: 'production', }]

                                  3. 使用其他配置语言

                                  webpack 接受以多种编程和数据语言编写的配置文件。支持的文件扩展名列表,可以在node-interpret包中找到。使用node-interpret,webpack 可以处理许多不同类型的配置文件。

                                  文档介绍:《使用不同语言进行配置(configuration languages)》

                                  3.1 TypeScript

                                  为了用 TypeScript 书写 webpack 的配置文件,必须先安装相关依赖:

                                  npm install --save-dev typescript ts-node @types/node @types/webpack

                                  使用 TypeScript 书写 webpack 的配置文件:

                                  // webpack.config.ts import path from 'path'; import webpack from 'webpack'; const config: webpack.Configuration = { mode: 'production', entry: './foo.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'foo.bundle.js' } }; export default config;

                                  3.2 Babel and JSX

                                  在以下的例子中,使用了JSXReact形式的 javascript)以及Babel来创建JSON形式的 webpack 配置文件:

                                  首先安装依赖:

                                  npm install --save-dev babel-register jsxobj babel-preset-es2015

                                  设置配置:

                                  // .babelrc { "presets": [ "es2015" ] } // webpack.config.babel.js import jsxobj from 'jsxobj'; // example of an imported plugin const CustomPlugin = config => ({ ...config, name: 'custom-plugin' }); export default ( );

                                  三. 模块

                                  1. 模块介绍

                                  开发中将程序分解成离散功能块,成为模块。

                                  而 webpack 模块能够以各种形式表达他们的依赖关系:

                                  • es6:import语句;
                                  • CommonJS:require()语句;
                                  • AMD:definerequire语句;
                                  • css/sass/less文件中的@import语句;
                                  • 样式(url(...))或 HTML 文件中的图片链接(image url);

                                  查看更多模块方法

                                  2. 模块解析

                                  使用resolver库来找到模块的绝对路径,帮助 webpack 找到 bundle 中需要引入的模块代码,这些代码包含在每个require/import语句中,在模块打包中,webpack 使用enhanced-resolve来解析文件路径

                                  webpack 解析规则:使用enhanced-resolvewebpack支持解析三种文件路径:

                                  • 绝对路径:

                                  import "/home/me/file"; import "C:\\Users\\me\\file";

                                  • 相对路径:

                                  import "../src/file1"; import "./file2";

                                  • 模块路径:

                                  import "module"; import "module/lib/file";

                                  模块将在resolve.modules中指定的所有目录中搜索,另外可以使用resolve.alias做初始化模块路径。

                                  解析器(resolver)检查路径是否指向文件或目录,如果是指向文件:

                                  • 如果有文件拓展名则直接打包;
                                  • 否则使用 [resolve.extensions] 选项作为文件扩展名来解析,配置解析器在解析中能够接受哪些扩展名(例如.js,.jsx)。

                                  如果是指向文件夹,则按照步骤找到正确拓展名的文件:

                                  • 如果文件夹中包含package.json文件,则按照顺序查找resolve.mainFields配置选项中指定的字段。并且package.json中的第一个这样的字段确定文件路径。
                                  • 如果不存在package.json文件或者package.json文件中的main字段没有返回一个有效路径,则按照顺序查找resolve.mainFiles配置选项中指定的文件名,看是否能在import/require目录下匹配到一个存在的文件名。
                                  • 文件扩展名通过resolve.extensions选项采用类似的方法进行解析。

                                  3. 解析 loader

                                  Loader 解析遵循与文件解析器指定的规则相同的规则。但是resolveLoader配置选项可以用来为 Loader 提供独立的解析规则。

                                  4. 缓存

                                  每个文件系统访问都被缓存,以便更快触发对同一文件的多个并行或串行请求。在观察模式下,只有修改过的文件会从缓存中摘出。如果关闭观察模式,在每次编译前清理缓存。

                                  有关上述配置的更多信息,请查看解析 API学习。

                                  四. 构建目标

                                  注意:webpack 的target属性不要和output.libraryTarget属性混淆。

                                  1. 用法

                                  在你的 webpack 配置中设置target的值:

                                  module.exports = { target: 'node' };

                                  在上面例子中,使用nodewebpack 会编译为用于「类 Node.js」环境(使用 Node.js 的require,而不是使用任意内置模块(如fspath)来加载 chunk)。

                                  更多详细的值,可以参考构建目标(targets)

                                  2. 多个 target

                                  尽管 webpack 不支持向target传入多个字符串,你可以通过打包两份分离的配置来创建同构的库:

                                  var path = require('path'); var serverConfig = { target: 'node', output: { path: path.resolve(__dirname, 'dist'), filename: 'lib.node.js' } //… }; var clientConfig = { target: 'web', // <=== 默认是 'web',可省略 output: { path: path.resolve(__dirname, 'dist'), filename: 'lib.js' } //… }; module.exports = [ serverConfig, clientConfig ];

                                  到此这篇关于Webpack核心概念的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持自由互联。