Skip to content

Commit 99ec547

Browse files
authored
v1.18.0 (polyfill type) (#126)
* v1.18.0 * fix: 错误的引用 * up deeps & corejs@3 * fix: less javascriptEnabled deprecated * fix: 垃圾 less * fix: less * UP * remove yarn.lock * doc: update * add 'proposalEnabled' * proposalEnabled -> proposalsEnabled * chore: version * chore: version
1 parent 2b863a5 commit 99ec547

File tree

9 files changed

+2392
-1007
lines changed

9 files changed

+2392
-1007
lines changed

build-config.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,16 @@ const apiUrl = "http://foobar.com/api" + 'test'
200200

201201
- **`optimization.addPolyfill`**
202202

203-
类型:`boolean`
203+
类型:`boolean``string`
204+
205+
是否开启自动 polyfill 功能,以及开启何种形式的 polyfill;开启后会根据 `targets.browsers` 参数自动实现对应的 polyfill;
204206

205-
是否开启自动 polyfill 功能,开启后会根据 `targets.browsers` 参数自动打包对应的 polyfill,并在作为独立的包被页面前置引用,`true` 启用,`false` 禁用
207+
| value | desc |
208+
| ------------- | ------------- |
209+
| `false` | 不开启 `polyfill` |
210+
| `true` | 开启 `polyfill`,使用默认的方式 (`"global"`) 进行 `polyfill` |
211+
| `"global"` | 开启基于 `@babel/preset-env``polyfill`,polyfill 会被作为独立的包被页面前置引用,会污染全局内置对象,适合普通应用 |
212+
| `"runtime"` | 开启基于 `@babel/plugin-transform-runtime``polyfill`,生成辅助函数以替换特定方法,不会污染全局命名空间,适用于工具类库 |
206213

207214
- **`optimization.extractCommon`**
208215

lib/constants/polyfill.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @file polyfill type
3+
* @author Surmon <i@surmon.me>
4+
*/
5+
6+
exports.polyfillType = {
7+
global: 'global',
8+
runtime: 'runtime'
9+
}
10+
11+
// 是否 polyfill 尚在提案阶段的 API
12+
exports.proposalsEnabled = false
13+
14+
exports.isGlobalPolyfill = type => {
15+
return type === exports.polyfillType.global || type === true
16+
}
17+
18+
exports.isRuntimePolyfill = type => {
19+
return type === exports.polyfillType.runtime
20+
}

lib/webpack-config/addons/add-polyfill.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@ const VirtualModulesPlugin = require('webpack-virtual-modules')
99

1010
const buildEnv = require('../../utils/build-env')
1111
const chunks = require('../../constants/chunks')
12+
const { proposalsEnabled, isGlobalPolyfill } = require('../../constants/polyfill')
1213

1314
module.exports = (webpackConfig, srcDir, srcPath, { addPolyfill }) => {
1415
const isProdEnv = buildEnv.get() === buildEnv.prod
1516

16-
if (!addPolyfill || !isProdEnv) {
17+
if (!isGlobalPolyfill(addPolyfill) || !isProdEnv) {
1718
return webpackConfig
1819
}
1920

2021
const mockFile = `${chunks.polyfill}.js`
22+
const coreJSEntry = proposalsEnabled
23+
? 'core-js'
24+
: 'core-js/stable'
2125

2226
return update(webpackConfig, {
2327
entry: {
@@ -27,7 +31,7 @@ module.exports = (webpackConfig, srcDir, srcPath, { addPolyfill }) => {
2731
* 1. 经过反复测试和确认,Babel 似乎认工作路径,如果 polyfill 与项目程序本身的路径不一致,则 useBuiltIns 失效
2832
* 2. 所以只能造一个假的路径为项目路径的虚拟文件,以模拟 '/xxx/project/src/polyfill.js'
2933
* 3. VirtualModulesPlugin 插件目前可确认的最高支持在 Webpack v4,如果后期升级 Webpack 则需检测此处
30-
X `[chunks.polyfill]: '@babel/polyfill'` -> 无法被 Babel 理解并替换
34+
X `[chunks.polyfill]: 'core-js'` -> 无法被 Babel 理解并替换
3135
X `path.resolve(__dirname, ... 'polyfill.js')` -> 无法产出合乎预期的包,始终为全量的 polyfill
3236
*/
3337
[chunks.polyfill]: path.resolve(srcPath, mockFile)
@@ -39,7 +43,10 @@ module.exports = (webpackConfig, srcDir, srcPath, { addPolyfill }) => {
3943
[
4044
path.join('./', srcDir, '/') + mockFile
4145
]: (
42-
`require('@babel/polyfill')`
46+
`
47+
require('${coreJSEntry}')
48+
require('regenerator-runtime/runtime')
49+
`
4350
)
4451
})
4552
]

lib/webpack-config/addons/add-transform.js

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const buildEnv = require('../../utils/build-env')
1111
const paths = require('../../utils/paths')
1212
const utils = require('../../utils')
1313
const transforms = require('../../constants/transforms')
14+
const { proposalsEnabled, isGlobalPolyfill, isRuntimePolyfill } = require('../../constants/polyfill')
1415

1516
const regexpEscape = s => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
1617

@@ -43,35 +44,39 @@ const makeBabelPlugin = plugin => (
4344
* 注意后续可能要修改这边逻辑,考虑会对 import / export 进行转换的不一定只有 env 这个 preset
4445
* @param {object} options babel options
4546
* @param {object} targets babel env targets: https://babeljs.io/docs/en/babel-preset-env#targets
46-
* @return {object}
47-
* TODO: 检查现在 webpack4 是不是还需要 modules: false 的逻辑
4847
*/
4948
const makeBabelLoaderOptions = (options, targets, { addPolyfill }) => {
5049
options = options || {}
5150

5251
const presets = options.presets || []
5352
const plugins = options.plugins || []
53+
const corejsOptions = {
54+
version: 3,
55+
proposals: proposalsEnabled
56+
}
5457

5558
const babelPresetEnvName = '@babel/preset-env'
56-
const presetPolyfillOptions = {
57-
useBuiltIns: 'entry',
58-
// corejs 选项在 @babel/preset-env 7.4.0 之后可用;
59-
// 若 @babel/preset-env 版本 >= 7.4.0,则此处需要显式指定版本为 2
60-
corejs: 2,
61-
}
6259
const defaultBabelPresetEnv = [babelPresetEnvName, {
63-
...(
64-
addPolyfill && buildEnv.get() === buildEnv.prod
65-
? presetPolyfillOptions
66-
: null
67-
),
60+
// https://babeljs.io/docs/en/babel-preset-env#modules
61+
// 将 ES6 module 转换为指定 module -> 不转换
6862
modules: false,
69-
targets
63+
targets,
64+
...(
65+
// global polyfill
66+
isGlobalPolyfill(addPolyfill)
67+
&& buildEnv.get() === buildEnv.prod
68+
&& {
69+
// https://babeljs.io/docs/en/babel-preset-env#usebuiltins
70+
useBuiltIns: 'entry',
71+
corejs: corejsOptions
72+
}
73+
)
7074
}]
7175

7276
const babelPluginTransformRuntimeName = '@babel/plugin-transform-runtime'
7377
const defaultBabelPluginTransformRuntime = [babelPluginTransformRuntimeName, {
74-
corejs: 2
78+
// https://babeljs.io/docs/en/babel-plugin-transform-runtime#corejs
79+
corejs: corejsOptions
7580
}]
7681

7782
const babelPresetEnv = presets.find(preset =>
@@ -98,9 +103,10 @@ const makeBabelLoaderOptions = (options, targets, { addPolyfill }) => {
98103
},
99104
plugins: {
100105
$set: (
101-
babelPluginTransformRuntime
102-
? []
103-
: [defaultBabelPluginTransformRuntime]
106+
// 用户未主动配置插件且启用了 runtime 类型的 polyfill,则应用插件
107+
!babelPluginTransformRuntime && isRuntimePolyfill(addPolyfill)
108+
? [defaultBabelPluginTransformRuntime]
109+
: []
104110
)
105111
.concat(plugins)
106112
.map(makeBabelPlugin)

lib/webpack-config/addons/common-chunks.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
const update = require('immutability-helper')
77
const chunks = require('../../constants/chunks')
88
const buildEnv = require('../../utils/build-env')
9+
const { isGlobalPolyfill } = require('../../constants/polyfill')
910

1011
module.exports = (config, optimization) => {
1112
const { addPolyfill } = optimization
1213
const optCommon = optimization.extractCommon
1314
const optVendor = optimization.extractVendor
1415

1516
const chunksName = (
16-
addPolyfill && buildEnv.get() === buildEnv.prod
17+
isGlobalPolyfill(addPolyfill) && buildEnv.get() === buildEnv.prod
1718
? chunk => chunk.name !== chunks.polyfill
1819
: 'all'
1920
)

lib/webpack-config/addons/gen-pages.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const buildEnv = require('../../utils/build-env')
1010
const paths = require('../../utils/paths')
1111
const utils = require('../../utils')
1212
const chunks = require('../../constants/chunks')
13+
const { isGlobalPolyfill } = require('../../constants/polyfill')
1314

1415
module.exports = (config, pageMap, publicUrl, optimization) => {
1516
const pages = Object.keys(pageMap).map(
@@ -26,7 +27,7 @@ module.exports = (config, pageMap, publicUrl, optimization) => {
2627
const baseChunks = []
2728

2829
if (buildEnv.get() === buildEnv.prod) {
29-
if (addPolyfill) {
30+
if (isGlobalPolyfill(addPolyfill)) {
3031
baseChunks.push(chunks.polyfill)
3132
}
3233
if (optCommon) {

0 commit comments

Comments
 (0)