-
Notifications
You must be signed in to change notification settings - Fork 274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[译] Webpack 2 有哪些新东西 #58
Comments
代码压缩功能不错 |
postMessage改为包含WS,不明何故。 |
ES6 导出混淆的意思可能是说可以在模块导出后,但是没有使用到,可以把导出的对象的属性名压缩掉。 |
@jxbb |
现在慢还是个病垢,希望V2 能提高编译速度 |
Tree-shaking 没提啊…… |
@JasinYip “针对 ES6 规范的优化”这节讲的就是 tree-shaking,只是没用这个术语。 |
顶一个,ES6 modules 已经等很久了。现在整个项目都是ES6,优化打包结果会小很多。 |
这里的意思是 webpack 在可以追踪导出的接口的使用情况时,可以把导出的接口名压缩成单字符属性。
混淆后:
|
@tuoxiansp 我译错了,我把 "possible" 看成 "impossible" 了。我回头改一下。 |
注意 module: {
- loaders: [
+ rules: [
{
test: /\.css$/,
- loaders: [
+ use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
- query: {
+ options: {
modules: true
}
]
}
]
} |
@blade254353074 |
mark |
请教一下这个是什么意思?不是一直都是异步的吗,我有点乱了-- |
@ImJoeHs 仔细读原文,就知道意思是原本如果chunk已经加载,则调用require.ensure是同步的。 |
@hax 惭愧惭愧,有中文就下意识偷懒了不看原文,是我伸手党了。谢谢回答! |
es2015-webpack预设没什么用啊,预设配置成["es2015", {"modules": false}]才有效果。 |
前天2.2正式 release 了,关于 Polyfill 的问题之前自己写了个简单插件,现在放出来,欢迎试用 😄 : |
[译] Webpack 2 有哪些新东西
Work in progress... This reflects stuff until 2.0.5-beta+
仍在开发中……本文只反映截至 2.0.5-beta+ 版本的情况。
Major changes
主要变更
ES6 Modules
ES6 模块
webpack 2 brings native support ES6 Modules. This means webpack now understands
import
andexport
without them being transformed to CommonJS:Webpack 2 将增加对 ES6 模块的原生支持。这意味着 Webpack 现在可以识别
import
和export
了,不需要先把它们转换成 CommonJS 模块的格式:Code Splitting with ES6
遵循 ES6 的代码拆分方式
The ES6 Loader spec defines
System.import
as method to load ES6 Modules dynamically on runtime.ES6 Loader 规范定义了
System.import
方法,用于在运行时动态加载 ES6 模块。Webpack threads
System.import
as splitpoint and puts the requested module in a separate chunk.Webpack 把
System.import
作为拆分点,然后把被请求的模块放入一个单独的 “块”(chunk)中。System.import
takes the module name as argument and returns a Promise.System.import
接受模块名作为参数,然后返回一个 Promise。Good news: Failure to load a chunk can be handled now.
顺便说个好消息:chunk 加载失败产生的错误现在可以被捕获了。
Dynamic expressions
动态表达式
It's possible to pass an partial expression to
System.import
. This is handled similar to expressions in CommonJS (webpack creates a context with all possible files).还可以把一个表达式作为参数传给
System.import
。表达式的处理方式类似于 CommonJS(Webpack 为每个可能的文件创建一个独立的上下文)。System.import
creates a separate chunk for each possible module.System.import
会令每个可能的模块都产生一个独立的 chunk。Mixing ES6 with AMD and CommonJS
混用 ES6、AMD 和 CommonJS 模块
As for AMD and CommonJS you can freely mix all three module types (even within the same file). Webpack behaves similar to babel in this case:
至于 AMD 和 CommonJS,你可以自由地混用所有这三种模块类型(哪怕在是在同一个文件内)。Webpack 在这种情况下的行为跟 Babel 类似:
babel and webpack
Babel 与 Webpack
The
es2015
babel preset transforms ES6 Modules to CommonJS by default. To use webpack to process ES6 Modules you should use thees2015-webpack
preset instead.在默认情况下,Babel 的
es2015
预设方案(preset)会把 ES6 模块转换为 CommonJS 格式。如果你想让 Webpack 来处理 ES6 模块,那你应该换用es2015-webpack
这个预设方案。ES6 specific optimizations
针对 ES6 规范的优化
The static nature of ES6 Modules allows some new kind of optimizations. In example in many cases it's possible to detect which exports are used and which aren't used.
ES6 模块与生俱来的静态特性允许我们采用一些新型的优化措施。比如说,在很多场景下,我们可以探测出哪些导出的接口会被用到,而哪些不会。
In cases in which webpack can say for sure that an export isn't used it omits the statement which exposes the export to other modules. Later the minimizer may flag the declaration as unused and omits it.
只要 Webpack 可以确定一个输出接口没有被别的模块用到,就会忽略那条输出语句。随后代码压缩工具就可以把那条声明标记为无用并丢弃。
In the following cases it's possible to detect usage:
在以下情况下,可以探测出接口的使用情况:
In the following cases it's not possible to detect usage:
而在以下情况下,无法探测出接口的使用情况:
import * as ...
System.import
import * as ...
语句System.import
语句ES6 export mangling
ES6 导出混淆
In cases where it's possible to track export usage, webpack can mangle export names to single char properties.
万一无法追踪导出接口的使用情况,Webpack 可以把导出的接口名混淆为单个字符的属性。(译注:抱歉,我不明白这句话。)
Configuration
配置
In the past environment variables are often used to handle different environments in the configuration file. Webpack 2 brings a new way to pass options to the configuration.
在过去的环境中,变量通常用来在配置文件中处理不同的环境。Webpack 2 引入了一种新方法,可以将选项传给配置。
The configuration file can export a function which returns the configuration. The function is called by the CLI and the value passed via
--env
is passed to the configuration function.配置文件可以导出一个函数,这个函数返回配置。这个函数会被 CLI(命令行界面)调用,而通过
--env
参数传过来的值会被传递给这个配置函数。You can pass a string (
--env dev
=>"dev"
) or a complex options object (--env.minimize --env.server localhost
=>{minimize: true, server: "localhost"}
). I would recommend using an object, because it's more extendable, but it's up to you.你可以传递一个字符串(
--env dev
→"dev"
),或者一个复杂的选项对象(--env.minimize --env.server localhost
→
{minimize: true, server: "localhost"}
)。我会推荐使用一个对象,因为那样更具扩展性,不过最后还是看你自己如何选择。Example
示例代码
Resolving options
解析选项
There was a major refactoring in the resolver (https://github.com/webpack/enhanced-resolve). This means the resolving option were changed too. Mostly simplification and changes that make it more unlikely to configure it incorrectly.
解析器有少量重构( https://github.com/webpack/enhanced-resolve )。这意味着解析选项也发生了变化。基本上是一些简化,以及变得更加不容易写错。
The new options are:
新选项如下:
Minor breaking changes
次要的破坏性变更
Promise
polyfillPromise
的 polyfillThe chunk loading stuff now relies on
Promise
being available. This means you need to provide aPromise
polyfill for older browsers.分块加载机制现在是依赖于
Promise
的。这表示你需要在旧版浏览器下提供一个 Promise 的 polyfill。The ES6 spec uses promises and I don't want to include a Promise polyfill in every bundle. So it's up the application developer to provide the polyfill if needed.
ES6 规范已经包含了 Promise,我不想在每个打包文件中都加入一个 Promise 的 polyfill。因此,如果需要的话,就要由应用的开发者来提供这个 polyfill 了。
Can I use Promises?
Promises 的兼容性情况 - CanIUse.com
Other polyfills
其它 polyfill
You need a
Object.defineProperty
polyfill for ES6 Module or if using themodule
object in other ways thanmodule.exports
,module.id
,module.loaded
ormodule.hot
.你需要一个
Object.defineProperty
的 polyfill 来实现 ES6 的模块特性。或者在以(除了module.exports
、module.id
、module.loaded
或module.hot
之外的)其它方式使用module
对象时,这个 polyfill 也是需要的。For ES6 Modules you also need a
Function.prototype.bind
polyfill.为了实现 ES6 的模块特性,你还需要一个
Function.prototype.bind
的 polyfill。That's not new but anyway: You need an
Object.keys
polyfill forrequire.context().keys()
.最后这一条也不算新鲜了,但还是提一下吧:你需要一个
Object.keys
的 polyfill 来运行require.context().keys()
。Loaders configuration
Loader 的配置
The loaders in the configuration now match to the
resourcePath
instead of theresource
. This means the query string is no longer included for matching.现在,配置文件所指定的各个 loader 的值只匹配
resourcePath
(资源路径),而不是以前的resource
(资源)。这表示 query string(查询字符串)不再参与匹配。This was an issue with bootstrap which complicates the
test
for bootstrap fonts and images from/\.svg$/
to/\.svg($|\?)/
. Now you can use the simple form.以前在使用 Bootstrap 时有一个问题,会把 Bootstrap 字体和图片的
test
字段搞复杂——必须把/\.svg$/
写成/\.svg($|\?)/
。现在你就可以直接使用那个简单的形式了。The loader in the configuration now resolves relative to the configuration file (or the
context
option in the configuration file if specified). This should fix some issues withnpm link
ed modules that are outside of the current package.配置文件所指定的各个 loader 现在是相对于配置文件进行解析的(但如果配置文件指定了
context
选项则以它为准)。在以前,如果某些外部模块是通过npm link
链接到当前包的,则会产生问题,现在应该都可以解决了。Another change allows the following syntax to configure loaders:
此外,我们将可以使用以下语法来配置 loader:
Loader options & minimize
Loader 选项以及代码压缩
The
UglifyJsPlugin
no longer puts loaders into minimize mode. Thedebug
option has been removed. Loaders should no longer read their options from the webpack configuration. Instead you need to provide these options with theLoaderOptionsPlugin
.UglifyJsPlugin
将不再把所有 loader 都切到代码压缩模式。debug
选项已经被移除。Loader 不应该再从 Webpack 的配置那里读取自己选项了。取而代之的是,你需要通过LoaderOptionsPlugin
来提供这些选项。This happens for separation of concern reasons. I want to disallow arbitrary keys in the configuration, to enable configuration validation.
决定使用这种设计是出于 “关注点分离” 的考虑。我希望在配置中禁止随意的字段名,以便让校验配置成为可能。
Plugins
插件
Many plugins now take option objects instead of multiple arguments. This happens because it is easier to extend. They throw an Error when the old argument style is passed.
现在许多插件将可以接受一个选项对象,而不是以前多个参数的形式。作为这个改动是因为这样更易于扩展。如果把旧版参数传给插件,插件会抛出一个错误。
HMR communication
“模块热替换” 的通信机制
In webpack 1 the update signal used the Web Messaging API (
postMessage
). Webpack 2 uses a standard event emitter to receive the event. This means WebSocket must be inline in the bundle.在 Webpack 1 中,更新信号用的是 Web Messaging API(
postMessage
)。而 Webpack 2 将使用一个标准的事件触发器来传递事件信号。这表示 WebSocket 必须内联到打包文件中。webpack-dev-server has inlined mode as default now.
webpack-dev-server 现在在默认情况下就处于内联模式。
This should allow to use the webpack-dev-server to update code in WebWorkers.
这应该使得我们可以用 webpack-dev-server 来更新 WebWorker 中的代码。
Occurrence order
出现顺序
The plugin is no longer needed and occurrence order is on by default.
OccurrenceOrderPlugin
这个插件将不再需要了,类似的功能默认就是开启的。Code Splitting
代码拆分
require.ensure
and AMDrequire
is now always async, even if the chunk was already loaded.require.ensure
和 AMD 的require
的加载方式现在都是异步的了,哪怕所需的 chunk 已经加载了。© Creative Commons BY-NC-ND 4.0 | 我要订阅 | 我要打赏
The text was updated successfully, but these errors were encountered: