Webpack configuration
To view all document pages:Full stack developmentFor more information.
Original link:Chapter 2 Configuration, the original advertising mode box block, reading experience is not good, so organize the text, easy to find.
There are two ways to configure a Webpack:
- Describe the configuration through a JavaScript file, such as using
webpack.config.js
Configuration in file; - When executing a Webpack executable, it is passed in through command line arguments, such as
webpack --devtool source-map
.
The two methods can be combined with each other, for example, through commands when executing a Webpack.webpack --config webpack-dev.config.js
Specify the configuration file before going.webpack-dev.config.js
Some configurations are described in the document.
According to configurationAffected functionsTo divide, can be divided into:
- EntryThe entrance of the configuration module;
- OutputConfigure how to output the final desired code;
- ModuleConfiguring rules for processing modules;
- ResolveConfigure rules for finding modules;
- PluginsConfigure extensions;
- DevServerConfigure DevServer;;
- Other configuration itemsOther scattered configuration items;
- Overall configuration structureDescribe the structure of each configuration item as a whole;
- Multiple configuration typesThe configuration file can return not only one Object, but also other return forms.
- Configuration summaryFind the rules for configuring Webpack and reduce the burden of thinking.
Entry
When searching for files with relative paths, the Webpack will take the context as the root directory, and the context defaults to the current working directory where the Webpack was started.
If you want to change the default configuration of context, you can set it in the configuration file:
module.exports = {
context: path.resolve(__dirname, 'app')
}
Note that the context must be a string of absolute paths. In addition, you can also use the parameters when starting the Webpack.webpack --context
To set the context.
Chunk name
The Webpack will give each generated Chunk a name, which is related to the configuration of Entry:
- If entry is a
string
Orarray
, only one Chunk will be generated, and the name of Chunk ismain
; - If entry is a
object
, there may be more than one Chunk, when the name of the Chunk isobject
The name of the key in the key-value pair.
Configure dynamic Entry
If there are multiple pages in the project that need to configure an Entry for each page Entry, but the number of these pages may continue to grow, then the entry configuration will be affected by other factors, resulting in a static value that cannot be written. The solution is to set Entry as a function to dynamically return the above-mentioned configuration. The code is as follows:
// 同步函数
entry: () => {
return {
a:'./pages/a',
b:'./pages/b',
}
};
// 异步函数
entry: () => {
return new Promise((resolve)=>{
resolve({
a:'./pages/a',
b:'./pages/b',
});
});
};
Output
output
Configure how to output the final desired code.output
Is aobject
, which contains a series of configuration items:
filename
output.filename
The name of the configuration output file, which is of type string. If there is only one output file, it can be written as static:
filename: 'bundle.js'
However, when there are multiple Chunk to output, templates and variables are needed. As mentioned earlier, the Webpack will give each Chunk a name, and the output file name can be distinguished according to the Chunk name:
filename: '[name].js'
In the code[name]
On behalf of the use of built-inname
Variable to replace[name]
In this case, you can think of it as a string module function, and each Chunk to be output will use this function to splice out the name of the output file.
variable name | Meaning |
---|---|
id | Unique identifier of Chunk, starting from 0 |
name | Chunk’s name |
hash | Hash value for unique identification of Chunk |
chunkhash | Hash value of Chunk content |
among themhash
Andchunkhash
The length of is specifiable.[hash:8]
On behalf of the 8-bit Hash value, the default is 20 bits.
Note that the ExtractTextWebpackPlugin plug-in is used
contenthash
To represent hash values instead ofchunkhash
The reason is that the content extracted by ExtractTextWebpackPlugin is the code content itself rather than Chunk composed of a group of modules.
chunkFilename
output.chunkFilename
Configure the file name of Chunk with no entry when outputting.chunkFilename
And abovefilename
Very similar, but chunkFilename is only used to specify the name of the file generated during runtime when Chunk is output. The usual Chunk scenario generated at run time is in use.CommonChunkPlugin
Useimport('path/to/module')
Dynamic loading isochronous. ChunkFilename supports built-in variables consistent with filename.
path
output.path
The configuration output file is stored in a local directory and must be an absolute path of type string. Jspath
Module to get absolute path:
path: path.resolve(__dirname, 'dist_[hash]')
publicPath
In complex projects, there may be some constructed resources that need to be loaded asynchronously, and the corresponding URL address is required to load these asynchronous resources.
output.publicPath
Configure the URL prefix to be published to online resources as string. The default value is an empty string''
That is, relative paths are used.
Upload the constructed resource file to CDN service to speed up the page opening. The configuration code is as follows:
filename:'[name]_[chunkhash:8].js'
publicPath: 'https://cdn.example.com/assets/'
At this time, when introducing JavaScript files, HTML published online needs to:
<script src='https://cdn.example.com/assets/a_12345678.js'></script>
Be careful when using this configuration item. Any carelessness will result in 404 error in resource loading.
output.path
Andoutput.publicPath
Both support string templates, with only one built-in variable:hash
Hash value representing a compilation operation.
crossOriginLoading
Some code blocks output by the Webpack may need to be loaded asynchronously, while asynchronous loading is done throughJSONP
In this way.JSONP
The principle of is to dynamically insert an<script src="url"></script>
Tag to load asynchronous resources.
output.crossOriginLoading
Is used to configure this asynchronously inserted tagcrossorigin
Value.
Script taggedcrossorigin
The property can take the following values:
-
false
(Default) Cookies; of users will not be brought when loading this script resource; -
use-credentials
When loading this script resource, the user’s Cookies will be brought along.
Usually with settingscrossorigin
To get detailed error information when asynchronously loaded scripts are executed.
LibraryTarget and library
They are needed when using Webpack to build a library that can be imported and used by other modules.
-
output.libraryTarget
Configure how libraries are exported. -
output.library
Configure the name of the export library.
If configuredoutput.library='LibraryName'
, the code to output and use is as follows:
// Webpack 输出的代码
var LibraryName = lib_code;
// 使用库的方法
LibraryName.doSomething();
Ifoutput.library
If it is empty, it will be directly output:lib_code
among them
lib_code
The code content guiding the outbound is a self-executing function with a return value.
They are usually used together.
output.libraryTarget
Is an enumeration type of string and supports the following configuration.
Var (default)
The library will be compiled throughvar
Assigned to Passlibrary
The variable that specifies the name.
commonjs
The written library will be exported through the CommonJS2 specification, and the output and use code are as follows:
// Webpack 输出的代码
module.exports = lib_code;
// 使用库的方法
require('library-name-in-npm').doSomething();
The CommonJS2 and CommonJS specifications are very similar, except that CommonJS can only be used
exports
Export, while CommonJS2 adds to CommonJSmodule.exports
The export method of.
Inoutput.libraryTarget
For commonjs2, configureoutput.library
There will be no point.
this
The library will be compiled throughthis
Assigned to Passlibrary
The specified name, output and code used are as follows:
// Webpack output code
this[‘LibraryName’] = lib_code;
//Method of using library
this.LibraryName.doSomething();
window
The library will be compiled throughwindow
Assigned to Passlibrary
The specified name, that is, mount the library to thewindow
On, the output and use codes are as follows:
// Webpack 输出的代码
window['LibraryName'] = lib_code;
// 使用库的方法
window.LibraryName.doSomething();
global
The library will be compiled throughglobal
Assigned to Passlibrary
The specified name, that is, mount the library to theglobal
On, the output and use codes are as follows:
// Webpack 输出的代码
global['LibraryName'] = lib_code;
// 使用库的方法
global.LibraryName.doSomething();
libraryExport
output.libraryExport
Configure which sub-modules of the modules to export need to be exported. It is only inoutput.libraryTarget
Set tocommonjs
Or ..commonjs2
Only when it is used can it be meaningful.
If the module source code to be exported is:
export const a=1;
export default b=2;
Now you want the code that builds the output to export only thea
, can putoutput.libraryExport
set ata
Then the code for building the output and how to use it will become as follows:
// Webpack 输出的代码
module.exports = lib_code['a'];
// 使用库的方法
require('library-name-in-npm')===1;
Module
Configure Loader
rules
The reading and parsing rules of the configuration module are usually used for configuration.Loader
. Its type is an array, and each item in the array describes how to process some files. Configure an itemrules
When roughly through the following ways:
-
Condition matching: Pass
test
、include
、exclude
Three configuration items to hit the file to which Loader applies the rule. -
Apply rules: Passes the selected file
use
Configuration items to apply Loader, can only apply a Loader or according toFrom back to frontA set of loaders can be applied in the order of. at the same time, parameters can be passed in to loaders respectively. -
Reset order: the execution order of a set of LoaderThe default is from right to leftThrough
enforce
Option allows one of the Loader to be executed first or last.
module: {
rules: [
{
// 命中 JavaScript 文件
test: /\.js$/,
// 用 babel-loader 转换 JavaScript 文件
// ?cacheDirectory 表示传给 babel-loader 的参数,用于缓存 babel 编译结果加快重新编译速度
use: ['babel-loader?cacheDirectory'],
// 只命中src目录里的js文件,加快 Webpack 搜索速度
include: path.resolve(__dirname, 'src')
},
{
// 命中 SCSS 文件
test: /\.scss$/,
// 使用一组 Loader 去处理 SCSS 文件。
// 处理顺序为从后到前,即先交给 sass-loader 处理,再把结果交给 css-loader 最后再给 style-loader。
use: ['style-loader', 'css-loader', 'sass-loader'],
// 排除 node_modules 目录下的文件
exclude: path.resolve(__dirname, 'node_modules'),
},
{
// 对非文本文件采用 file-loader 加载
test: /\.(gif|png|jpe?g|eot|woff|ttf|svg|pdf)$/,
use: ['file-loader'],
},
]
}
When Loader needs to pass in many parameters, you can also use aObject
To describe, for example, the abovebabel-loader
The configuration has the following code:
use: [
{
loader:'babel-loader',
options:{
cacheDirectory:true,
},
// enforce:'post' 的含义是把该 Loader 的执行顺序放到最后
// enforce 的值还可以是 pre,代表把 Loader 的执行顺序放到最前面
enforce:'post'
},
// 省略其它 Loader
]
In the above exampletest include exclude
The configuration items of the three hit files only pass in a string or regular, but they all support array types, using the following:
{
test:[
/\.jsx?$/,
/\.tsx?$/
],
include:[
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'tests'),
],
exclude:[
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, 'bower_modules'),
]
}
Between each item in the array isOrIf the file path meets any condition in the array, it will be hit.
noParse
noParse
Configuration items enable the Webpack to ignore recursive parsing and processing of some files that do not adopt modularity, which has the advantage of improving construction performance. The reason is that some libraries, such as jQuery and ChartJS, are large and do not adopt modular standards. It is time-consuming and meaningless for Webpack to parse these files.
noParse
Is an optional configuration item and needs to be of typeRegExp
、[RegExp]
、function
One of them.
For example, if you want to ignore jQuery and ChartJS, you can use the following code:
// 使用正则表达式
noParse: /jquery|chartjs/
// 使用函数,从 Webpack 3.0.0 开始支持
noParse: (content)=> {
// content 代表一个模块的文件路径
// 返回 true or false
return /jquery|chartjs/.test(content);
}
Note that neglected files should not contain
import
、require
、define
Such as modular statements, otherwise it will cause the built code to contain modular statements that cannot be executed in the browser environment.
parser
Because the Webpack uses modular JavaScript files as its entry, it has built-in parsing capabilities for modular JavaScript and supportsAMD
、CommonJS
、SystemJS
、ES6
.
parser
The property allows finer-grained configuration of which module syntax is to be parsed and which is not, andnoParse
Configuration items differ in thatparser
Can be accurate to the grammatical level, andnoParse
You can only control which files are not parsed.parser
Use the following:
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'],
parser: {
amd: false, // 禁用 AMD
commonjs: false, // 禁用 CommonJS
system: false, // 禁用 SystemJS
harmony: false, // 禁用 ES6 import/export
requireInclude: false, // 禁用 require.include
requireEnsure: false, // 禁用 require.ensure
requireContext: false, // 禁用 require.context
browserify: false, // 禁用 browserify
requireJs: false, // 禁用 requirejs
}
},
]
}
Resolve
After the Webpack is started, all dependent modules will be found from the configured portal modules.Resolve
Configure how the Webpack finds the file corresponding to the module. The Webpack has built-in JavaScript modular syntax parsing function. By default, the rules agreed in the modular standard will be used to find it, but you can also modify the default rules according to your own needs.
alias
resolve.alias
Configuration items map the original import path to a new import path through aliases. For example, use the following configuration:
// Webpack alias 配置
resolve:{
alias:{
components: './src/components/'
}
}
When you passimport Button from 'components/button'
When importing, is actuallyalias
Equivalent replaced byimport Button from './src/components/button'
.
Abovealias
The meaning of configuration is to import thecomponents
Replace keywords with./src/components/
.
Doing so may hit too many import statements.alias
Also supports$
Symbol to narrow the scope to hit only import statements that end with keywords:
resolve:{
alias:{
'react$': '/path/to/react.min.js'
}
}
react$
It will only hitreact
At the end of the import statement, that is, only theimport 'react'
Replace keywords withimport '/path/to/react.min.js'
.
mainFields
There are some third-party modules that provide some code for different environments. For example, two codes using ES5 and ES6 are provided respectively. The positions of these two codes are written inpackage.json
The document reads as follows:
{
"jsnext:main": "es/index.js",// 采用 ES6 语法的代码入口文件
"main": "lib/index.js" // 采用 ES5 语法的代码入口文件
}
Webpack will be based onmainFields
To decide which code to use first,mainFields
The default is as follows:
mainFields: ['browser', 'main']
The Webpack will go in the order in the array.package.json
When searching in the file, only the first one found will be used.
If you want to give priority to the ES6 code, you can configure it as follows:
mainFields: ['jsnext:main', 'browser', 'main']
extensions
When the import statement does not have a file suffix, the Webpack will automatically take the suffix and try to access whether the file exists.resolve.extensions
Used to configure the suffix list used in the attempt. The default is:
extensions: ['.js', '.json']
modules
resolve.modules
To configure which directories the Webpack will go to look for third-party modules, the default is to go only.node_modules
Look under the catalog.
Sometimes some modules in your project will be heavily dependent on and imported by other modules. due to the uncertain location of other modules, the relative path of imported module files will be calculated for different files. this path is sometimes very long, like thisimport '../../../components/button'
At this time you can usemodules
Configuration item optimization, if those modules imported in large quantities are all in./src/components
Under the directory, putmodules
Configured to:
modules:['./src/components','node_modules']
After that, you can simply passimport 'button'
Import.
descriptionFiles
resolve.descriptionFiles
The configuration describes the file name of the third-party module, that ispackage.json
Documents. The default is as follows:
descriptionFiles: ['package.json']
enforceExtension
resolve.enforceExtension
If configured totrue
All import statements must have a file suffix, such as before openingimport './foo'
Can work normally, must be written after openingimport './foo.js'
.
enforceModuleExtension
enforceModuleExtension
AndenforceExtension
The effect is similar, butenforceModuleExtension
Only rightnode_modules
The following modules take effect.
enforceModuleExtension
Common collocationenforceExtension
Use inenforceExtension:true
, because most of the imported statements in the installed third-party modules do not have a file suffix, so at this time through the configurationenforceModuleExtension:false
To be compatible with third-party modules.
Plugins
Plugin is used to extend the functions of Webpack. Various plugins allow Webpack to do almost anything related to construction.
Configure Plugin
Plugin’s configuration is simple.plugins
Configuration items accept an array, and each item in the array is an instance of Plugin to be used. Plugin requires parameters to pass throughConstructorIncoming.
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
module.exports = {
plugins: [
// 所有页面都会用到的公共代码提取到 common 代码块中
new CommonsChunkPlugin({
name: 'common',
chunks: ['a', 'b']
}),
]
};
The difficulty in using Plugin lies in mastering the configuration items provided by Plugin itself, rather than how to access Plugin in Webpack.
DevServer
To configure DevServer, you must use thedevServer
In addition to passing in parameters, you can also pass in through command line parameters. Note that only throughDevServer
In the configuration file when starting the WebpackdevServer
Will take effect because the functions corresponding to these parameters are all provided by DevServer and the Webpack itself does not know them.devServer
Configuration item.
hot
devServer.hot
Configure whether the module hot swap function is enabled.
DevServer
The default behavior is to realize real-time preview by automatically refreshing the entire page after discovering that the source code has been updated, and to realize real-time preview by replacing the old module with the new module without refreshing the entire page after turning on the module hot replacement function.
inline
DevServer’s real-time preview function relies on a proxy client injected into the page to accept commands from DevServer and be responsible for refreshing the page.
devServer.inline
It is used to configure whether the proxy client is automatically injected into the Chunk to be run on the page. The default is automatic injection. DevServer will depend on whether you open it or not.inline
To adjust its automatic refresh policy:
- If on
inline
, DevServer will control web page refresh through proxy client when the changed code is built. - If closed
inline
, DevServer will have no direct control over the web pages to be developed. Then it will passiframe
To run the web page to be developed, refresh it when the changed code is built.iframe
To realize real-time preview.
If you want to use DevServer to refresh the web page automatically to realize real-time preview, the most convenient method is to open it directly.inline
.
historyApiFallback
devServer.historyApiFallback
For convenient development of single-page applications using the HTML5 History API.
This type of one-page application requires the server to return a corresponding HTML file for any hit route, for example, when accessinghttp://localhost/user
Andhttp://localhost/home
Return at all timesindex.html
File, browser-side JavaScript code will analyze the current page status from the URL and display the corresponding interface.
ConfigurationhistoryApiFallback
The simplest way is:
historyApiFallback: true
This will cause any request to returnindex.html
File, which can only be used for applications with only one HTML file.
If your application consists of multiple single-page applications, it requires DevServer to return different HTML files according to different requests. the configuration is as follows:
historyApiFallback: {
// 使用正则匹配命中路由
rewrites: [
// /user 开头的都返回 user.html
{ from: /^\/user/, to: '/user.html' },
{ from: /^\/game/, to: '/game.html' },
// 其它的都返回 index.html
{ from: /./, to: '/index.html' },
]
}
contentBase
devServer.contentBase
Configure the file root directory of the DevServer HTTP server. By default, it is the current execution directory, usually the root directory of the project. In general, you do not need to set it unless you have additional files to be served by DevServer. For example, you want to put thepublic
The directory is set as the file root directory of DevServer server. you can configure it as follows:
devServer:{
contentBase: path.join(__dirname, 'public')
}
There are two types of files exposed by DevServer server through HTTP service, which need to be pointed out that may confuse you:
- Expose local files.
- Expose the results built by the Webpack. Since the built results are handed over to DevServer, you cannot find the built files locally when using DevServer.
contentBase
Can only be used to configure rules that expose local files. You can do this bycontentBase:false
To close expose local files.
headers
devServer.headers
Configuration items can inject some HTTP response headers into HTTP responses using the following:
devServer:{
headers: {
'X-foo':'bar'
}
}
host
devServer.host
The configuration item is used to configure the address to which the DevServer service listens.
For example, if you want other devices in the LAN to access your local service, you can bring it with you when you start DevServer.--host 0.0.0.0
.host
The default value for is127.0.0.1
That is, only the local can access DevServer’s HTTP service.
port
devServer.port
The configuration item is used to configure the port on which DevServer service listens. it is used by default8080
Port. If8080
The port is already occupied by other programs8081
If8081
Or is it occupied and used?8082
And so on.
allowedHosts
devServer.allowedHosts
Configure a white list. Only the HOST of HTTP request will normally return in the list. Use the following:
allowedHosts: [
// 匹配单个域名
'host.com',
'sub.host.com',
// host2.com 和所有的子域名 *.host2.com 都将匹配
'.host2.com'
]
disableHostCheck
devServer.disableHostCheck
The configuration item is used to configure whether to turn off HOST checking for HTTP requests for DNS rebinding.
DevServer only accepts local requests by default, and can accept requests from any HOST after shutdown. It is usually used with--host 0.0.0.0
Use, because you want other devices to access your local service, but the access is directly through the IP address instead of HOST access, so you need to turn off HOST check.
https
DevServer uses HTTP protocol service by default, and it can also use HTTPS protocol service. In some cases you must use HTTPS, for example, HTTP2 and Service Worker must run on HTTPS. The easiest way to switch to HTTPS service is:
devServer:{
https: true
}
DevServer will automatically generate an HTTPS certificate for you.
If you want to use your own certificate, you can configure it like this:
devServer:{
https: {
key: fs.readFileSync('path/to/server.key'),
cert: fs.readFileSync('path/to/server.crt'),
ca: fs.readFileSync('path/to/ca.pem')
}
}
clientLogLevel
devServer.clientLogLevel
Configure the log level at the client, which will affect what you see in the browser developer tools console.
clientLogLevel
Yesenumeration type, which can take one of the following valuesnone | error | warning | info
. The default isinfo
Level, which outputs all types of logs, is set tonone
No log can be output.
compress
devServer.compress
Configure whether gzip compression is enabled.boolean
Is of type, which defaults tofalse
.
open
devServer.open
It is used to automatically use the default browser on your system to open the web page to be developed when DevServer starts and is built for the first time. It also providesdevServer.openPage
The configuration item is used to open the webpage of the specified URL.
Other configuration items
Target
target
Configuration items enable Webpack to build code for different operating environments. Target can be one of the following:
Target value | describe |
---|---|
web | For browsers(Default)All code is centralized in one file |
node | Js, userequire Statement to load Chunk code |
async-node | Js, load Chunk code asynchronously. |
webworker | For WebWorker |
electron-main | ForElectronMain thread |
electron-renderer | For Electron Rendering Threads |
For example, when you set uptarget:'node'
Js native module statement is imported into the source coderequire('fs')
Will be retained,fs
The contents of the module will not be packed into Chunk.
Devtool
devtool
Configure how Webpack generates Source Map, the default value isfalse
I.e. no Source Map is generated. if you want to generate Source Map for the built code to facilitate debugging, you can configure it as follows:
module.export = {
devtool: 'source-map'
}
Watch and WatchOptions
The listening mode of Webpack was introduced earlier. It supports listening for file updates and recompiling when files change. The listening mode is turned off by default when using the Webpack, and the following configuration is required to turn it on:
module.export = {
watch: true
}
When using DevServer, listening mode is turned on by default.
In addition, Webpack also provideswatchOptions
Configuration items can be used to control the listening mode more flexibly as follows:
module.export = {
// 只有在开启监听模式时,watchOptions 才有意义
// 默认为 false,也就是不开启
watch: true,
// 监听模式运行时的参数
// 在开启监听模式时,才有意义
watchOptions: {
// 不监听的文件或文件夹,支持正则匹配
// 默认为空
ignored: /node_modules/,
// 监听到变化发生后会等300ms再去执行动作,防止文件更新太快导致重新编译频率太高
// 默认为 300ms
aggregateTimeout: 300,
// 判断文件是否发生变化是通过不停的去询问系统指定文件有没有变化实现的
// 默认每1000豪秒去问1次
poll: 1000
}
}
Externals
External is used to tell which modules are not to be packaged in the code to be built by the Webpack, that is to say, these templates are provided by the external environment, and the Webpack can ignore them when packaging.
Some JavaScript operating environments may have built-in global variables or modules, such as the following code in your HTML HEAD tag:
<script src="path/to/jquery.js"></script>
After jQuery was introduced, global variablesjQuery
It will be injected into the JavaScript running environment of the web page.
If you want to import and use jQuery in source code that uses modularity, you may need to do this:
import $ from 'jquery';
$('.my-element');
After construction, you will find the contents of jQuery library contained in the output Chunk, which results in jQuery library appearing twice, wasting load flow, and it is better that the contents of jQuery library will not be contained in Chunk.
Externals configuration items are designed to solve this problem.
viaexternals
You can tell that the Webpack JavaScript runtime environment has built-in those global variables. For these global variables, global variables are used directly instead of being packaged into code. To solve the above problems, it can be configured as followsexternals
:
module.export = {
externals: {
// 把导入语句里的 jquery 替换成运行环境里的全局变量 jQuery
jquery: 'jQuery'
}
}
ResolveLoader
ResolveLoader is used to tell the Webpack how to find Loader, because when using Loader, it is referenced by its package name. The Webpack needs to find the actual code of Loader according to the configured Loader package name to call Loader to process the source file.
The default configuration of ResolveLoader is as follows:
module.exports = {
resolveLoader:{
// 去哪个目录下寻找 Loader
modules: ['node_modules'],
// 入口文件的后缀
extensions: ['.js', '.json'],
// 指明入口文件位置的字段
mainFields: ['loader', 'main']
}
}
This configuration item is often used to load the local Loader.
Overall configuration structure
The previous chapters described the specific meaning of each configuration item separately, but did not describe their location and data structure. The following is a code to describe it clearly:
const path = require('path');
module.exports = {
// entry 表示 入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
// 类型可以是 string | object | array
entry: './app/entry', // 只有1个入口,入口只有1个文件
entry: ['./app/entry1', './app/entry2'], // 只有1个入口,入口有2个文件
entry: { // 有2个入口
a: './app/entry-a',
b: ['./app/entry-b1', './app/entry-b2']
},
// 如何输出结果:在 Webpack 经过一系列处理后,如何输出最终想要的代码。
output: {
// 输出文件存放的目录,必须是 string 类型的绝对路径。
path: path.resolve(__dirname, 'dist'),
// 输出文件的名称
filename: 'bundle.js', // 完整的名称
filename: '[name].js', // 当配置了多个 entry 时,通过名称模版为不同的 entry 生成不同的文件名称
filename: '[chunkhash].js', // 根据文件内容 hash 值生成文件名称,用于浏览器长时间缓存文件
// 发布到线上的所有资源的 URL 前缀,string 类型
publicPath: '/assets/', // 放到指定目录下
publicPath: '', // 放到根目录下
publicPath: 'https://cdn.example.com/', // 放到 CDN 上去
// 导出库的名称,string 类型
// 不填它时,默认输出格式是匿名的立即执行函数
library: 'MyLibrary',
// 导出库的类型,枚举类型,默认是 var
// 可以是 umd | umd2 | commonjs2 | commonjs | amd | this | var | assign | window | global | jsonp ,
libraryTarget: 'umd',
// 是否包含有用的文件路径信息到生成的代码里去,boolean 类型
pathinfo: true,
// 附加 Chunk 的文件名称
chunkFilename: '[id].js',
chunkFilename: '[chunkhash].js',
// JSONP 异步加载资源时的回调函数名称,需要和服务端搭配使用
jsonpFunction: 'myWebpackJsonp',
// 生成的 Source Map 文件名称
sourceMapFilename: '[file].map',
// 浏览器开发者工具里显示的源码模块名称
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]',
// 异步加载跨域的资源时使用的方式
crossOriginLoading: 'use-credentials',
crossOriginLoading: 'anonymous',
crossOriginLoading: false,
},
// 配置模块相关
module: {
rules: [ // 配置 Loader
{
test: /\.jsx?$/, // 正则匹配命中要使用 Loader 的文件
include: [ // 只会命中这里面的文件
path.resolve(__dirname, 'app')
],
exclude: [ // 忽略这里面的文件
path.resolve(__dirname, 'app/demo-files')
],
use: [ // 使用那些 Loader,有先后次序,从后往前执行
'style-loader', // 直接使用 Loader 的名称
{
loader: 'css-loader',
options: { // 给 html-loader 传一些参数
}
}
]
},
],
noParse: [ // 不用解析和处理的模块
/special-library\.js$/ // 用正则匹配
],
},
// 配置插件
plugins: [],
// 配置寻找模块的规则
resolve: {
modules: [ // 寻找模块的根目录,array 类型,默认以 node_modules 为根目录
'node_modules',
path.resolve(__dirname, 'app')
],
extensions: ['.js', '.json', '.jsx', '.css'], // 模块的后缀名
alias: { // 模块别名配置,用于映射模块
// 把 'module' 映射 'new-module',同样的 'module/path/file' 也会被映射成 'new-module/path/file'
'module': 'new-module',
// 使用结尾符号 $ 后,把 'only-module' 映射成 'new-module',
// 但是不像上面的,'module/path/file' 不会被映射成 'new-module/path/file'
'only-module$': 'new-module',
},
alias: [ // alias 还支持使用数组来更详细的配置
{
name: 'module', // 老的模块
alias: 'new-module', // 新的模块
// 是否是只映射模块,如果是 true 只有 'module' 会被映射,如果是 false 'module/inner/path' 也会被映射
onlyModule: true,
}
],
symlinks: true, // 是否跟随文件软链接去搜寻模块的路径
descriptionFiles: ['package.json'], // 模块的描述文件
mainFields: ['main'], // 模块的描述文件里的描述入口的文件的字段名称
enforceExtension: false, // 是否强制导入语句必须要写明文件后缀
},
// 输出文件性能检查配置
performance: {
hints: 'warning', // 有性能问题时输出警告
hints: 'error', // 有性能问题时输出错误
hints: false, // 关闭性能检查
maxAssetSize: 200000, // 最大文件大小 (单位 bytes)
maxEntrypointSize: 400000, // 最大入口文件大小 (单位 bytes)
assetFilter: function (assetFilename) { // 过滤要检查的文件
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
}
},
devtool: 'source-map', // 配置 source-map 类型
context: __dirname, // Webpack 使用的根目录,string 类型必须是绝对路径
// 配置输出代码的运行环境
target: 'web', // 浏览器,默认
target: 'webworker', // WebWorker
target: 'node', // Node.js,使用 `require` 语句加载 Chunk 代码
target: 'async-node', // Node.js,异步加载 Chunk 代码
target: 'node-webkit', // nw.js
target: 'electron-main', // electron, 主线程
target: 'electron-renderer', // electron, 渲染线程
externals: { // 使用来自 JavaScript 运行环境提供的全局变量
jquery: 'jQuery'
},
stats: { // 控制台输出日志控制
assets: true,
colors: true,
errors: true,
errorDetails: true,
hash: true,
},
devServer: { // DevServer 相关的配置
proxy: { // 代理到后端服务接口
'/api': 'http://localhost:3000'
},
contentBase: path.join(__dirname, 'public'), // 配置 DevServer HTTP 服务器的文件根目录
compress: true, // 是否开启 gzip 压缩
historyApiFallback: true, // 是否开发 HTML5 History API 网页
hot: true, // 是否开启模块热替换功能
https: false, // 是否开启 HTTPS 模式
},
profile: true, // 是否捕捉 Webpack 构建的性能信息,用于分析什么原因导致构建性能不佳
cache: false, // 是否启用缓存提升构建速度
watch: true, // 是否开始
watchOptions: { // 监听模式选项
// 不监听的文件或文件夹,支持正则匹配。默认为空
ignored: /node_modules/,
// 监听到变化发生后会等300ms再去执行动作,防止文件更新太快导致重新编译频率太高
// 默认为300ms
aggregateTimeout: 300,
// 判断文件是否发生变化是不停的去询问系统指定文件有没有变化,默认每秒问 1000 次
poll: 1000
},
};
Multiple configuration types
In addition to exporting an Object to describe the configuration required by the Webpack, there are other more flexible ways to simplify the configuration of different scenarios.
Export a Function
Most of the time you need to build multiple copies of code from the same source code, for example, one for development and one for publishing online.
If you export an Object to describe the configuration required by the Webpack, you need to write two files. One for the development environment and one for the online environment. And then pass at startupwebpack --config webpack.config.js
Specify which profile to use.
By exporting a Function, the above requirements can be fulfilled by writing only one configuration file through JavaScript’s flexible control configuration.
How to export a Function is as follows:
const path = require('path');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
module.exports = function (env = {}, argv) {
const plugins = [];
const isProduction = env['production'];
// 在生成环境才压缩
if (isProduction) {
plugins.push(
// 压缩输出的 JS 代码
new UglifyJsPlugin()
)
}
return {
plugins: plugins,
// 在生成环境不输出 Source Map
devtool: isProduction ? undefined : 'source-map',
};
};
When you run the Webpack, you pass in 2 arguments to this function, which are:
-
env
: Webpack-specific environment variable for the current runtime.env
Is an Object. When reading, directly access the property of Object, and set it with parameters when starting the Webpack. For example, the start command iswebpack --env.production --env.bao=foo
When, thenenv
The value of is{"production":"true","bao":"foo"}
. -
argv
: Represents all parameters passed in through the command line when starting the Webpack, for example--config、--env、--devtool
, can be passed throughwebpack -h
Lists all command line arguments supported by the Webpack.
As far as the above configuration files are concerned, the webpack, which executes the command during development, builds code that is convenient for debugging, and executes it when it is necessary to build code that is published online.webpack --env.production
Build compressed code.
Export a function that returns Promise
In some cases, you cannot return an Object that describes the configuration synchronously. The Webpack also supports exporting a function that returns Promise, using the following:
module.exports = function(env = {}, argv) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
// ...
})
}, 5000)
})
}
Export Multiple Configurations
In addition to exporting only one configuration, the Webpack also supports exporting an array that can contain each configuration and each configuration will be built once.
Use the following:
module.exports = [
// 采用 Object 描述的一份配置
{
// ...
},
// 采用函数描述的一份配置
function() {
return {
// ...
}
},
// 采用异步函数描述的一份配置
function() {
return Promise();
}
]
The above configuration will cause the Webpack to perform three different builds for the three configurations.
This is especially suitable for building a library to be uploaded to Npm warehouse with Webpack, because the library may need to contain codes in various modular formats, such as CommonJS and UMD.
Configuration summary
Judging from the previous configuration, there are many options, and many functions are built into the Webpack.
You don’t have to remember them all. You just need to understand the principles and core concepts of the Webpack to determine which module the options belong to, and then check the detailed usage documents.
In general, you can use the following experience to judge how to configure the Webpack:
- WantSource fileAdd to the build process to be controlled and configured by Webpack
entry
. - Want to customizeThe location and name of the output file, configuration
output
. - Want to customizeStrategies for Finding Dependent Modules, configuration
resolve
. - Want to customizeStrategies for parsing and converting files, configuration
module
, usually configurationmodule.rules
Loader in. - Most other requirements may be implemented through Plugin, configuration
plugin
.