您的位置:首页 > Web前端 > Webpack

Webpack学习之你该更新了从V1到V2(三)

2017-04-07 11:00 423 查看
这部分没有接触
Webpack1.x
的读者可以跳过(减号代表不用,+代表新增)

resolve.root, resolve.fallback, resolve.modulesDirectories

这些选项取而代之的是一个配置项
resolve.modules


resolve: {
-   root: path.join(__dirname, "src")
+   modules: [
+     path.join(__dirname, "src"),
+     "node_modules"
+   ]
}


resolve.extensions

这个选项不再需要传递一个空字符串。 这种行为被
resolve.enforceExtension
代替。

resolve.*

更多相关改动和一些不常用的配置项在此不一一列举,大家如果在实际项目中用到可以到
resolving
中进行查看。

module.loaders
变为了
module.rules


旧版本中
loaders
配置项将被功能更为强大的
rules
取代,同时考虑到新旧版本的兼容,之前旧版本的
module.loaders
的相关写法依旧有效,
loaders
中的相关配置项也依旧可以被识别。

新的
loader
配置规则会变得更加通俗易用,因此官方也非常推荐用户能及时按
module.rules
中的最新配置进行调整升级。

module: {
-   loaders: [
+   rules: [
{
test: /\.css$/,
-       loaders: [
-         "style-loader",
-         "css-loader?modules=true"
+       use: [
+         {
+           loader: "style-loader"
+         },
+         {
+           loader: "css-loader",
+           options: {
+             modules: true
+           }
+         }
]
},
{
test: /\.jsx$/,
loader: "babel-loader", // Do not use "use" here
options: {
// ...
}
}
]
}


链式
loaders

webpack1.x
中类似,
loaders
继续支持链式写法,可将正则匹配到的资源结果在
loader
之间进行共享传递。在
wepback2.x
中,用户可通过
use
项来指定需要用到的
loaders
列表,而在
webpack1.x
中,如果需要配置多个
loaders
则需要依靠简单的 !符来分隔,这种语法出于新旧兼容的考虑,只会在
module.loaders
中生效。

module: {
-   loaders: [{
+   rules: [{
test: /\.less$/,
-     loader: "style-loader!css-loader!less-loader"
+     use: [
+       "style-loader",
+       "css-loader",
+       "less-loader"
+     ]
}]
}


module
名称自动补全
-loader
模块的功能将被移除

在配置
loader
时,官方不再允许省略
-loader
扩展名。

module: {
rules: [
{
use: [
-         "style",
+         "style-loader",
-         "css",
+         "css-loader",
-         "less",
+         "less-loader",
]
}
]
}


当然,如果你想继续保持之前的省略写法,你可以在
resolveLoader.moduleExtensions
中开启默认扩展名配置,不过这种做法并不被官方推荐。

+ resolveLoader: {
+   moduleExtensions: ["-loader"]
+ }


json-loader
无需安装

当我们需要读取
json
格式文件时,我们不再需要安装任何
loader
webpack2.x
中将会内置
json-loader
,自动支持
json
格式的读取。

module: {
rules: [
-     {
-       test: /\.json/,
-       loader: "json-loader"
-     }
]
}


这样做,官方声明式尽可能消除在
webpack
,
node.js
browserify
之间的环境差异。

loader
配置项将默认从
context
中读取

webpack 1
中的一些特殊的
loader
在读取对应资源时,需要通过
require.resolve
指定后才能指定生效。从
webpack 2
后,配置
loaders
直接从
context中
进行读取。

这就解决了一些在使用
npm link
或引用模块之外的
context
造成的模块重复导入的问题。

配置中可以删除如下代码:

module: {
rules: [
{
// ...
-       loader: require.resolve("my-loader")
+       loader: "my-loader"
}
]
},
resolveLoader: {
-   root: path.resolve(__dirname, "node_modules")
}


module.preLoaders
module.postLoaders
将被移除

module: {
-   preLoaders: [
+   rules: [
{
test: /\.js$/,
+       enforce: "pre",
loader: "eslint-loader"
}
]
}


UglifyJsPlugin
中的
sourceMap
配置项

UglifyJsPlugin
中的
sourceMap
默认项将从
true
变为
false


这就意味着你编译压缩,或者想读取原始脚本信息的行数时出现
uglifyjs
警告,你需要手动开启
UglifyJsPlugin
的配置项:
sourceMap: true


devtool: "source-map",
plugins: [
new UglifyJsPlugin({
+     sourceMap: true
})
]


UglifyJsPlugin
的警告配置

UglifyJsPlugin
中的
compress.warnings
默认项将从
true
变为
false


这就意味着当你想看到
uglifyjs
警告时,你需要将
compress.warnings
手动设置为
true


devtool: "source-map",
plugins: [
new UglifyJsPlugin({
+     compress: {
+       warnings: true
+     }
})
]


UglifyJsPlugin
最小化
loaders

UglifyJsPlugin
将不再支持让
Loaders
最小化文件。

loader
的最小化文件模式将会在
webpack 3
或者后续版本中被彻底取消掉.

为了兼容部分旧式
loader
,你可以通过插件去处理,比如

plugins: [
+   new webpack.LoaderOptionsPlugin({
+     minimize: true
+   })
]


DedupePlugin
已经被移除

webpack.optimize.DedupePlugin
将不被支持

BannerPlugin
配置项

BannerPlugin
将不再允许接受两个参数,而是只提供一个对象配置项

plugins: [
-    new webpack.BannerPlugin('Banner', {raw: true, entryOnly: true});
+    new webpack.BannerPlugin({banner: 'Banner', raw: true, entryOnly: true});
]


OccurrenceOrderPlugin
如今已经默认

OccurrenceOrderPlugin
已经默认被允许,已经可以不被配置了

plugins: [
// webpack 1
-   new webpack.optimize.OccurenceOrderPlugin()
// webpack 2
-   new webpack.optimize.OccurrenceOrderPlugin()
]


ExtractTextWebpackPlugin
配置项将有所改变

ExtractTextPlugin 1.0.0
webpack2
将无法使用,你需要安装新版本去支持它

npm install --save-dev extract-text-webpack-plugin


当然此插件的一些语法发生了变化

ExtractTextPlugin.extract


module: {
rules: [
{
test: /.css$/,
-      loader: ExtractTextPlugin.extract("style-loader", "css-loader", { publicPath: "/dist" })
+      use: ExtractTextPlugin.extract({
+        fallback: "style-loader",
+        use: "css-loader",
+        publicPath: "/dist"
+      })
}
]
}


new ExtractTextPlugin({options})


plugins: [
-  new ExtractTextPlugin("bundle.css", { allChunks: true, disable: false })
+  new ExtractTextPlugin({
+    filename: "bundle.css",
+    disable: false,
+    allChunks: true
+  })
]


全量动态加载资源

只有使用一个表达式的资源依赖引用
require(expr)
,将创建一个空的
context
,而不是一个
context
的完整目录。

当在
es2015
的模块化中无法工作时,请最好重构这部分的代码,如果无法进行修改这部分代码,你可以在
ContextReplacementPlugin
中来提示编译器做出正确处理。

CLI
使用自定义参数作为配置项

如果你随意将自定义参数通过
CLI
传入到配置项中,如:

webpack --custom-stuff


// webpack.config.js
var customStuff = process.argv.indexOf("--custom-stuff") >= 0;
/* ... */
module.exports = config;


你会发现这将不会被允许,
CLI
的执行将会遵循更为严格的标准。

取而代之的是用一个接口来做传递参数配置。这应该是新的代替方案,未来的工具开发也可能依赖于此。

webpack --env.customStuff


module.exports = function(env) {
var customStuff = env.customStuff;
/* ... */
return config;
};


require.ensure
AMD require
将采用异步式调用

require.ensure
amd require
将默认采用异步的加载方式来调用,而非之前的当模块请求加载完成后再在回调函数中同步触发。

require.ensure
将基于原生的Promise对象重新实现,当你在使用
require.ensure
时请确保你的运行环境默认支持
Promise
对象,如果缺少则推荐使用安装
polyfill
.

Loader
的配置项将通过
options
来设置

webpack.config.js
中将不再允许使用自定义属性来配置
loader
,必须通过
options
,在
ts
配置项中的自定义属性将无法在被在
webpack2
中正确使用:

module.exports = {
...
module: {
rules: [{
test: /\.tsx?$/,
loader: 'ts-loader'
}]
},
// does not work with webpack 2
ts: { transpileOnly: false }
}


什么是
options
?

这是一个非常好的提问,严格意义上来说
options
用来配置
webpack
如今有两种方式。

首先
options
应该被称作
query
,作为一种类似字符串的形式被追加到每一个
loader
的命名后面。

module.exports = {
...
module: {
rules: [{
test: /\.tsx?$/,
loader: 'ts-loader?' + JSON.stringify({ transpileOnly: false })
}]
}
}


options
也可作为一个独立的对象来处理


module.exports = {
...
module: {
rules: [{
test: /\.tsx?$/,
loader: 'ts-loader',
options:  { transpileOnly: false }
}]
}
}


LoaderOptionsPlugin
上下文(
context
)

部分
loader
需要配置
context
信息, 并且支持从配置文件中读取。这需要
loader
通过用长选项传递进来。

为了兼容部分旧式的
loader
配置,也可以采用如下插件的形式来进行配置:

plugins: [
+   new webpack.LoaderOptionsPlugin({
+     options: {
+       context: __dirname
+     }
+   })
]


debug

debug
作为
loader
中的一个调试模式选项。在
webpack2
中,则需要
loader
通过用长选项传递进来。

loader
debug
模式在
webpack3.0
或者后续版本中将会被移除。

为了兼容部分旧式的
loader
配置,也可以采用如下插件的形式来进行配置:

- debug: true,
plugins: [
+   new webpack.LoaderOptionsPlugin({
+     debug: true
+   })
]


ES2015
用于代码分离

webpack1
中,你需要使用
require.ensure
实现块的懒加载,如:

require.ensure([], function(require) {
var foo = require("./module");
});


es2015
loader
中通过定义
import()
作为资源加载方法,当读取到符合
ES2015
规范的模块时,可实现模块中的内容在运行时动态加载。

webpack
在处理
import()
时可以实现按需提取开发中所用到的模块资源,再写入到各个独立的块中。
webpack2
已经支持原生的
ES6
的模块加载器了,这意味着
webpack 2
能够理解和处理
import
export
了。

import()
支持将模块名作为参数出入并且返回一个
Promise
对象。

function onClick() {
import("./module").then(module => {
return module.default;
}).catch(err => {
console.log("Chunk loading failed");
});
}


好消息:当我们的模块加载失败时可以被捕获到了,因为这些都会遵循
Promise
的标准来实现。

值得注意的地方:
require.ensure
的第三个参数选项允许使用简单的块命名方式,但是
import API
中将不被支持,如果你希望继续采用函数式的写法,你可以继续使用
require.ensure


require.ensure([], function(require) {
var foo = require("./module");
}, "custom-chunk-name");


动态表达式

现在
import()
中的传参可支持部分表达式的写法了,如果之前有接触过
CommonJS
require()
表达式写法,应该不会对此感到陌生。

import()
会针对每一个读取到的
module
创建独立块。

function route(path, query) {
return import(`./routes/${path}/route`)
.then(route => new route.Route(query));
}
// This creates a separate chunk for each possible route


混用
ES2015
AMD
CommonJS

AMD
CommonJS
模块加载器中,你可以混合使用所有(三种)的模块类型(即使是在同一个文件里面)。

// CommonJS consuming ES2015 Module
var book = require("./book");

book.currentPage;
book.readPage();
book.default === "This is a book";


// ES2015 Module consuming CommonJS
import fs from "fs"; // module.exports map to default
import { readFileSync } from "fs"; // named exports are read from returned object+

typeof fs.readFileSync === "function";
typeof readFileSync === "function";


如果要支持
es2015
的一些东西,.babelrc文件需要进行一些设置

{
"presets": [
["es2015", { "modules": false }]
]
}


模板字符串

webpack
中的资源参数已经开始支持模板字符串了,这意味着你可以使用如下的配置写法:

- require("./templates/" + name);
+ require(`./templates/${name}`);


配置
Promise

webpack
现在在配置文件项中返回
Promise
了,这就允许你在配置中可以进行一些异步的写法了,如下所示:

webpack.config.js


module.exports = function() {
return fetchLangs().then(lang => ({
entry: "...",
// ...
plugins: [
new DefinePlugin({ LANGUAGE: lang })
]
}));
};


Loader
支持更多的高级写法

webpack
中的
loader
配置支持如下写法:

module: {
rules: [
{
resource: /filename/, // matches "/path/filename.js"
resourceQuery: /^\?querystring$/, // matches "?querystring"
issuer: /filename/, // matches "/path/something.js" if requested from "/path/filename.js"
}
]
}


更多的
CLI
参数项

如下有更多的
CLI
参数项可用:

--define process.env.NODE_ENV="production" 支持直接配置DefinePlugin.

--display-depth 能显示每个entry中的module的资源深度

--display-used-exports 能显示每个module中依赖使用了哪些资源.

--display-max-modules 能限制显示output中引用到的资源数量 (默认显示15个).

-p 修改:process.env.NODE_ENV 为 "production"


Cacheable
缓存项

Loaders
现在将默认开启资源缓存了,如果你不希望
loader
读缓存则需要在配置中指明:

// Cacheable loader
module.exports = function(source) {
-   this.cacheable();
return source;
}


// Not cacheable loader
module.exports = function(source) {
+   this.cacheable(false);
return source;
}


Complex options
复合参数项写法

webpack1
中的
loader
参数项中只支持
JSON.stringify
这种
json
字符串的写法;
webpack2
中的
loader
参数项中已经可以支持任意的
JS
对象的写法了。

使用复合选项时会有一个限制,你需要配置一个
ident
作为项来保证能正确引用到其他的
loader
,这意味着通过配置我们可以在内联写法中去调用对应依赖的加载器,如下:

require("some-loader??by-ident!resource")


{
test: /.../,
loader: "...",
options: {
ident: "by-ident",
magic: () => return Math.random()
}
}


这种方式并不常用。我们在使用
style-loader
生成一个模块时,需要依赖前面的
loader
计算的结果。

// style-loader generated code (simplified)
var addStyle = require("./add-style");
var css = require("-!css-loader?{"modules":true}!postcss-loader??postcss-ident");

addStyle(css);


如果你使用比较的复杂选项时,你可能就会使用
ident
了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐