使用不同语言配置js/ts/coffee:
- 为了用
TypeScript书写webpack的配置文件,必须先安装相关依赖:
npm install --save-dev typescript ts-node @types/node @types/webpack
- 类似的,为了使用
CoffeeScript来书写配置文件, 同样需要安装相关的依赖:
npm install --save-dev coffee-script
module.exports导出为多种类型:
output
module--rule--loader
module主要是根据rule(规则)来配置loader(插件)
解析resolve
webpack在启动后会从配置的入口模块触发找出所有依赖的模块,Resolve配置webpack如何寻找模块对应的文件。webpack内置JavaScript模块化语法解析功能,默认会采用模块化标准里约定好的规则去寻找,但你可以根据自己的需要修改默认的规则。
下面介绍几个常用的配置项
1.
alias:配置项通过别名来把原导入路径映射成一个新的导入路径。
- 例如使用以下配置:
resolve:{
alias:{
components: './src/components/'
}
}
- 当你通过
import Button from 'components/button'导入时,实际上被alias等价替换成了import Button from './src/components/button' - 配置根目录
resolve:{
alias:{
'@': resolve('src'),
}
}
- 还有很多种配置方式,请参看官网
2.
mainFields:有一些第三方模块会针对不同环境提供几分代码。 例如分别提供采用ES5和ES6的2份代码,这2份代码的位置写在package.json文件里,如下:
{
// 采用 ES6 语法的代码入口文件
"jsnext:main": "es/index.js",
// 采用 ES5 语法的代码入口文件
"main": "lib/index.js"
}
Webpack会根据mainFields的配置去决定优先采用那份代码,mainFields默认如下:
mainFields: ['browser', 'main']
Webpack会按照数组里的顺序去package.json文件里寻找,只会使用找到的第一个。- 假如你想优先采用
ES6的那份代码,可以这样配置:
mainFields: ['jsnext:main', 'browser', 'main']
3.
extensions:在导入语句没带文件后缀时,Webpack会自动带上后缀后去尝试访问文件是否存在。resolve.extensions用于配置在尝试过程中用到的后缀列表,默认是:
extensions: ['.js', '.json']
- 也就是说当遇到
require('./data')这样的导入语句时,Webpack会先去寻找./data.js文件,如果该文件不存在就去寻找./data.json文件, 如果还是找不到就报错。 - 假如你想让
Webpack优先使用目录下的TypeScript文件,可以这样配置:
extensions: ['.ts', '.js', '.json']
4.
modules:resolve.modules配置Webpack去哪些目录下寻找第三方模块,默认是只会去node_modules目录下寻找。
- 有时你的项目里会有一些模块会大量被其它模块依赖和导入,由于其它模块的位置分布不定,针对不同的文件都要去计算被导入模块文件的相对路径,这个路径有时候会很长,就像这样
import '../../../components/button'这时你可以利用modules配置项优化,假如那些被大量导入的模块都在./src/components目录下,把modules配置成
modules:['./src/components','node_modules']
- 后,你可以简单通过
import 'button'导入。
5.
descriptionFiles:resolve.descriptionFiles配置描述第三方模块的文件名称,也就是package.json文件。默认如下:
descriptionFiles: ['package.json']
6.
enforceExtension:如果配置为true所有导入语句都必须要带文件后缀, 例如开启前import './foo'能正常工作,开启后就必须写成import './foo.js'
7.
enforceModuleExtension:和enforceExtension作用类似,但它只对node_modules下的模块生效。
- 通常搭配
enforceExtension使用,在enforceExtension:true时,因为安装的第三方模块中大多数导入语句没带文件后缀, 所以这时通过配置enforceModuleExtension:false来兼容第三方模块。
插件plugins
优化(optimization)
从 webpack 4 开始,会根据你选择的 mode 来执行不同的优化,不过所有的优化还是可以手动配置和重写。
devServer
webpack-dev-server能够用于快速开发应用程序
- 假设你主机名为
localhost:8080, 请求 API 的url是http://your_api_server.com/user/list '/proxy':如果点击某个按钮,触发请求 API 事件,这时请求url是http://localhost:8080/proxy/user/list。changeOrigin:如果true,那么http://localhost:8080/proxy/user/list变为http://your_api_server.com/proxy/user/list。但还不是我们要的url。pathRewrite:重写路径。匹配/proxy,然后变为'',那么url最终为http://your_api_server.com/user/list。
devtool
此选项控制是否生成,以及如何生成
source map。
7中SourceMap模式
| 模式 | 解释 |
|---|---|
| eval | 每个module会封装到 eval 里包裹起来执行,并且会在末尾追加注释 //@ sourceURL. |
| source-map | 生成一个SourceMap文件. |
| hidden-source-map | 和 source-map 一样,但不会在 bundle 末尾追加注释. |
| inline-source-map | 生成一个 DataUrl 形式的 SourceMap 文件. |
| eval-source-map | 每个module会通过eval()来执行,并且生成一个DataUrl形式的SourceMap |
| cheap-source-map | 生成一个没有列信息(column-mappings)的SourceMaps文件,不包含loader的 sourcemap(譬如 babel 的 sourcemap) |
| cheap-module-source-map | 生成一个没有列信息(column-mappings)的SourceMaps文件,同时 loader 的 sourcemap 也被简化为只包含对应行的。 |
- 注1:webpack 不仅支持这 7 种,
而且它们还是可以任意组合上面的eval、inline、hidden关键字,
就如文档所说,你可以设置 souremap 选项为:
cheap-module-inline-source-map。
- 注2:如果你的modules里面已经包含了SourceMaps,
你需要用source-map-loader 来和合并生成一个新的 SourceMaps。
统计信息stats
构建时命令行的日志显示方案:
1、是webpack的stats的优化方式
2、优化日志还可以使用插件friendly-errors-webpack-plugin,使用案例如下:
const FriendlyErrorsPlugin =
require('friendly-errors-webpack-plugin')
new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is:
http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: ...
})
自动配置端口的npm包:portfinder
功能描述——获取当前可用的port:vue-cli配置好了,一旦端口被占用,报错,再次运行时会打开:8080+1,依次类推...8080+n
官网地址:www.npmjs.com/package/por…
其他配置
- 构建目标(
targets)告知webpack为目标(target)指定一个环境。默认为web:编译为类浏览器环境里可用。 - 监听模式(
watch)默认为false;若为true,则可配置watchOptions - 外部扩展(
externals):配置选项提供了「从输出的bundle中排除依赖」;可将公共模块如loadsh/jquery等配置在这里 - 性能(
performance):配置如何展示性能提示 - 其他......
webpack配置过程中用到的path
Node.js自带的path 模块提供了一些用于处理文件路径的小工具。创建 main.js 文件,代码如下所示:
var path = require("path");
// 格式化路径
console.log('normalization : ' +
path.normalize('/test/test1//2slashes/1slash/tab/..'));
// 连接路径
console.log('joint path : ' +
path.join('/test', 'test1', '2slashes/1slash', 'tab', '..'));
// 转换为绝对路径
console.log('resolve : ' + path.resolve('main.js'));
// 路径中文件的后缀名
console.log('ext name : ' + path.extname('main.js'));
运行:$ node main.js ,代码执行结果如下:
normalization : /test/test1/2slashes/1slash
joint path : /test/test1/2slashes/1slash
resolve : /web/com/1427176256_27423/main.js
ext name : .js
webpack-merge使用说明
配置文件被分成了许多不同的部分,那么必须以某种方式来组合他们,通常就是合并数组和对象,
webpack-merge很好的做到了这一点。
webpack-merge做了两件事:它允许连接数组并合并对象,而不是覆盖组合。如下所示:
const merge = require("webpack-merge");
merge(
{a : [1],b:5,c:20},
{a : [2],b:10, d: 421}
)
//合并后的结果
{a : [1,2] ,b :10 , c : 20, d : 421}
那么,如何合并配置文件呢?
1.首先将webpack-merge添加到项目中
npm install webpack-merge --save-dev
2.设置各个配置文件的连接
//webpack.config.js
const commConfig = require("./config/webpack.comm");
const developmentConfig = requie("./config/webpack.development");
const productionConfig = require("./config/webpack.production")
const merge = require("webpack-merge");
module.exports = mode => {
if(mode === "production"){
return merge(commConfig,productionConfig,{mode});
}
return merge(commConfig,developmentConfig,{mode});
}
//注:上面代码利用mode的值来判断是开发环境还是生产环境