一文速览Webpack
栏目: JavaScript · 发布时间: 6年前
内容简介:入口,Webpack执行构建的第一步将从entry开始,可抽象成输入;输出结果,在Webpack经过一系列处理并得到最终想要的代码后输出结果;模块转换器,用于将模块的原内容按照需求转换成新内容;
入口,Webpack执行构建的第一步将从entry开始,可抽象成输入;
module.exports = {
entry: './main.js'
};
复制代码
output
输出结果,在Webpack经过一系列处理并得到最终想要的代码后输出结果;
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist');
}
};
复制代码
loader
模块转换器,用于将模块的原内容按照需求转换成新内容;
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist');
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader?minimize'],
}
]
}
};
复制代码
plugins
扩展插件,在Webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果或我们想做的事情;
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist');
},
module: {
rules: [
{
test: /\.css$/,
loaders: ExtractTextPlugin.extract({
use: ['css-loader']
})
}
]
},
plugins: [
new ExtractTextPlugin({
fliename: `[name]_[contenthash:8].css`,
})
]
};
复制代码
module
模块,在Webpack里一切皆模块,一个模块对应一个文件。Webpack会从配置的entry开始递归找出所有依赖的模块;
chunk
代码块,一个chunk由多个模块组合而成,用于代码合并与分割;
总结: Webpack在启动后会从Entry里配置的Module开始,递归解析Entry依赖的所有Module。每找到一个Module,就会根据配置的Loader去找出对应的转换规则,对Module进行转换后,再解析出当前Module依赖的Module。这些模块会以Entry为单位进行分组,一个Entry及其所有依赖的Module被分到一个组也就是一个Chunk。最后Webpack会将所有Chunk转换成文件输出,在整个流程中,Webpack会在恰当的时机执行Plugin里定义的逻辑。
2. 基本配置
1. Entry
- context
Webpack在寻找相对路径的文件时会以context为根目录,context默认为当前所在的工作目录, 注意context必须是一个绝对路径的字符串 。
module.exports = {
context: path.resolve(__dirname, 'app'),
};
复制代码
- Entry类型
| 类型 | 例子 | 含义 |
|---|---|---|
| String | './main.js' | 入口模块的文件路径,可以是相对路径 |
| Array | ['./main.js', './app.js'] | 入口模块的文件路径,可以是相对路径 |
| Object | {a: './main.js', b: './app.js'} | 配置多个入口,每个入口生成一个chunk |
- chunk的名称
chunk的名称和entry的配置有关,如果entry是一个String或Array,只会生成一个chunk;如果entry是一个Object,就会生成多个chunk,名称为Object中的key。
- 配置动态Entry
如果不确定有多少个页面入口,可以设置为一个函数动态的返回entry配置;
// 同步函数
entry: () => {
return {
a: './page1/index',
b: './page2/index'
}
}
// 异步函数
entry: () => {
return new Promise( (resolve) => {
resolve({
a: './page1/index',
b: './page2/index'
})
})
}
复制代码
2. Output
- filename
filename是配置输出的文件名称,为string类型,如果只有一个输出文件可以写死为bundle.js,但是有多个输出时可以借助模板变量 [name].js
,常用的变量包括:
| 变量名称 | 含义 |
|---|---|
| id | Chunk的唯一标识,默认从0开始 |
| name | Chunk的名称 |
| hash | Chunk的唯一标识的Hash值,[hash:8]代表取8位Hash值,默认是20位 |
| chunkhash | Chunk内容的Hash值,取值同上 |
- chunkFilename
用于指定在运行过程中生成的Chunk在输出时的文件名称,常见场景为使用CommonChunkPlugin;支持和filename一致的内置变量;
- path
配置输出文件的本地目录,为string类型的绝对路径,支持字符串模板,内置变量只有一个Hash;
module.exports = {
output: {
path: path.resolve(__dirname, 'dist_[hash]')
}
};
复制代码
- publicPath
配置发布到线上资源的URL前缀,为string类型的相对路径,默认为'',也支持字符串模板,内置变量只有一个Hash;
module.exports = {
output: {
filename: '[name]_[chunkhash:8].js',
publicPath: 'https://XX.cdn.com/static/'
}
};
复制代码
- crossOriginLoading
Webpcak输出的部分代码块可能需要异步加载,是通过JSONP方式实现的,所以可以在 <script>
标签中设置crossorigin属性,常用来获取异步加载的脚本执行时的详细错误信息。
| crossorigin属性值 | 含义 |
|---|---|
| anonymous(默认) | 在加载此脚本资源时 不会 带上用户的cookie |
| use-credentials | 在加载此脚本资源时 会 带上用户的cookie |
- LibraryTarget和library
当用Webpack去构建一个可以被其他模块导入使用的库时,需要用到LibraryTarget和library,它们通常搭配在一起使用,推荐使用 Rollup 来构建基础库;
LibraryTarget配置以何种方式导出库,常用的有var/this/commonjs/window/global等; Library配置导出库的名称,配合LibraryTarget一起使用; 复制代码
- LibraryExport
配置为要导出的模块中哪些子模块需要被导出,它只有在output.libraryTarget被设置为commonjs或者commonjs2时使用才有意义;
// 某模块源代码
export const a = 1;
export default b = 2;
// 如果在output.libraryExport设置为a;那么将构建输出的代码和使用方法将变成以下内容:
// Webpack输出的代码
module.export = lib_code['a'];
// 使用库的方法
require('library-name') === 1;
复制代码
3. Module
- 配置Loader
rules配置模块的读取和解析规则,通常用来配置Loader。类型为数组,数组里的每一项都描述了如何处理部分文件,每一项大致有如下三种方式来完成;
- 条件匹配 : 通过 test、include、exclude 三个配置项来选中Loader要处理的文件;
- 应用规则 : 对选中的文件通过 use 配置项来应用Loader,也可以是一个,也可以是按照从后往前的顺序一组Loader,同时可以分别向Loader传入参数;
- 重要顺序 : 一组Loader的默认顺序是从右往左执行的,通过 enforce 选项可以将其中一个Loader放在最前( pre )或最后( post );
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true
},
enforce: 'post'
}],
include: path.resolve(__dirname, 'src'),
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
exclude: path.resolve(__dirname, 'node_modules')
}
]
}
};
复制代码
- noParse
该可选配置项可以让Webpack忽略对部分没采用模块化的文件的递归解析和处理,从而提高构建性能,类型为RegExp、[RegExp]、Function中的一种, 注意被忽略的文件里不能包含import、require、define等模块化语句 ,不然会导致在浏览器中无法执行该模块化语句;
// 正则形式
noParse: /jquery|chartjs/
// 函数形式
noParse: (content) => {
return /jquery|chartjs/.test(content);
}
复制代码
- parser
该配置项可以精确到语法层面,让Webpack只解析对应的模块化文件;
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'],
include: path.resolve(__dirname, 'src'),
parser: {
amd: false,
commonjs: true,
requirejs: false,
harmony: true
}
}
]
}
};
复制代码
4. Resolve
- alias
该配置项通过别名来将原导入路径映射成一个新的导入路径;
module.exports = {
resolve: {
alias: {
@components: './src/common/components',
@assets: './src/common/assets'
}
}
};
复制代码
- mainFields
有一些第三方模块会针对不同的环境提供几份代码,例如分别提供ES5和ES6两份代码,Webpack会根据mainFields的配置去决定优先采用哪份代码,如果想优先采用ES6的代码,则可以这样配置:
mainFields: ['jsnext:main', 'browser', 'main'], 复制代码
- extensions
在导入语句没带文件后缀时,Webpack会自动带上后缀尝试访问文件是否存在,默认是:
extensions: ['.js', '.json'], 复制代码
如果我们想让Webpack优先使用typescript文件,则可以这样配置:
extensions: ['.ts', '.js', '.json'] 复制代码
- modules
配置Webpack去哪些目录下寻找第三方模块,有时候我们项目中的大量模块会放在common下面,则可以这样去配置:
modules: ['./src/common', 'node_modules'] 复制代码
- descriptionFiles
该配置项是描述第三方模块的文件名称,也就是package.json文件,默认如下:
descriptionFiles: ['package.json'] 复制代码
- enforceExtension
如果resolve.enforceExtension为true,则所有导入语句都必须带后缀,如import './main.js';
- enforceModuleExtension
和resolve.enforceExtension作用类似, 专门针对node_modules下的模块生效 ,因为第三方模块大部分是不带后缀的,如果resolve.enforceExtension设置为true了,需要把resolve.enforceModuleExtension设为false来兼容第三方模块;
5. Plugin
Plugin的配置很简单,plugins接收一个数组,数组中的每一项都是一个Plugin的实例,Plugin的参数通过构造函数传入;
module.exports = {
plugins: [
new CommonChunkPlugin({
name: 'common',
chunks: ['a', 'b']
})
]
};
复制代码
6. DevServer
- hot
开启模块热替换功能,在不刷新整个页面的情况下,通过用新模块替换老模块来做到实时预览;
- inline
用于配置是否将这个代理客户端自动注入将运行在页面中的chunk里,默认自动注入;
-- 如果开启inline,则devserver会在构建变化后的代码时通过代理客户端控制网页刷新;
-- 如果关闭inline,则devserver会通过iframe的方式去运行要开发的网页,在构建完变化后的代码时,会通过刷新iframe来实现实时预览,这时需要去http://localhost:8080/webpack-dev-server/ 实时预览自己的网页;
- historyApiFallback
用于方便的开发使用了HTML5的History API的单页应用,总是返回同一个html文件,浏览器会从URL里解析出当前页面的状态,从而显示对应的界面;
- contentBase
用来配置devserver HTTP服务器的文件根目录,在默认情况下为当前的执行目录,通常是项目的根目录,所以在一般情况下不必设置;
- headers
可以在http响应中注入一些http响应头,使用如下:
module.exports = {
devServer: {
headers: {
'x-cookie': 12345
}
}
};
复制代码
- host
用于配置devServer服务监听的地址,如果想让局域网的其他设备访问自己的本地服务,则可以在启动devserver时带上参数--host 0.0.0.0;
- port
用于配置devServer服务监听的端口,默认使用8080端口,如果80端口被其他程序占用则依次+1类推;
- allowedHosts
配置一个白名单列表,只有http请求的host在该列表中才会正常返回;
- disableHostCheck
配置是否关闭用于DNS重新绑定的http请求的host检查,devserver默认只接受本地的请求,关闭后可以接收来自任意host的请求;
- https
devsever默认使用http服务,在某些情况下需要使用https服务时,可以开启此配置,此时devsever会自动为我们在本地生成一份https证书,这时需要重启服务,如HTTP2和Service Worker就必须运行在https上;
- clientLogLevel
配置客户端的日志等级,会影响我们在浏览器控制台里看到的内容,默认为info级别,即输出所以类型(none/error/warning/info)的日志;
- compress
配置是否启用Gzip压缩,为Boolean类型,默认为false;
- open
用于在devserver启动且第一次构建完成时,自动用系统默认浏览器打开我们开发的页面,还提供了openPage配置项来打开指定URL的页面;
7. 其它
- Target
target配置可以让Webpack构建除针对不同运行环境的代码,常见的有:
| target值 | 含义 |
|---|---|
| web | 针对浏览器(默认),所有代码都集中在一个文件里 |
| node | 针对nodejs,使用require语句加载chunk代码 |
| async-node | 针对nodejs,异步加载chunk代码 |
| webworker | 针对webworker |
| electron-mian | 针对Electron主线程 |
| electron-render | 针对Electron渲染线程 |
- Devtool
配置Webpack如何生成Source Map,默认值是false即不生成,若想构建出的代码生成Source Map方便调试,则可以这样配置:
module.exports = {
devtool: 'source-map'
};
复制代码
- Watch和WatchOptions
Webpack支持监听文件更新,在文件发生变化时重新编译,监听模式默认是关闭的,如想打开则配置为:
module.exports = {
watch: true
};
复制代码
在使用devserver时,监听模式默认开启;除此之外,还可以灵活的控制监听模式;
module.exports = {
watch: true,
watchOptions: {
// 不监听的文件或文件夹,支持正则匹配
ignored: /node_modules/,
// 监听到变化后会等300ms再去执行,防抖
// 默认是300ms
aggregateTimeout: 300,
// 判断文件是否发生变化通过不停地询问系统指定文件有没有变化
// 默认每秒询问1000次
poll: 1000
}
};
复制代码
- Externals
用于告诉Webpack要构建的代码中使用了哪些不用被打包的模块,也就是说这些模版是外部环境提供的,Webpack在打包时可以忽略它们;
module.exports = {
externals: {
jquery: 'jQuery'
}
};
复制代码
- ResloveLoader
用来告诉Webapck如何去寻找Loader,该配置项常用来加载本地的Loader,默认配置如下:
module.exports = {
resolveLoader: {
modules: ['node_modules'],
extensions: ['js', 'json'],
mainFields: ['loader', 'main']
}
};
复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Rationality for Mortals
Gerd Gigerenzer / Oxford University Press, USA / 2008-05-02 / USD 65.00
Gerd Gigerenzer's influential work examines the rationality of individuals not from the perspective of logic or probability, but from the point of view of adaptation to the real world of human behavio......一起来看看 《Rationality for Mortals》 这本书的介绍吧!