date-fns 2 - 无法进行 tree-shaking 工作
date-fns 2 - can't get tree-shaking to work
我无法理解 date-fns v.2 tree-shaking 功能的工作原理...
为了帮助我,我做了一个非常简单的项目:
date-fns 2.1.0
webpack 4.39.3
typescript 3.6.2
测试包含2个文件,一个作为"library",另一个作为运行的代码,就这么简单...
import ParseDate from './parse-date'
const parse = new ParseDate();
const result = parse.getExpirationDate({ months: 3 });
console.log(result);
但问题是,虽然我只要求使用 tree-shaking 使用 6 个库
import { addYears, addMonths, addWeeks, addDays, addHours, addMinutes } from 'date-fns';
来自他们的 docs:
// Without tree-shaking:
import format from 'date-fns/format'
import parse from 'date-fns/parse'
// With tree-shaking:
import { format, parse } from 'date-fns'
webpack 正在捆绑整个 date-fns 库,这是 2 个文件的结果,726Kb !!
> npm run build
> date_fns_test@1.0.0 build C:\Users\balexandre\date_fns_test
> tsc && webpack
Hash: 419a712549fc2309f21e
Version: webpack 4.39.3
Time: 820ms
Built at: 2019-09-09 17:27:36
Asset Size Chunks Chunk Names
bundle.js 726 KiB main [emitted] main
Entrypoint main = bundle.js
chunk {main} bundle.js (main) 441 KiB [entry] [rendered]
> ./src/index.js main
[./src/index.js] 410 bytes {main} [depth 0] [built]
single entry ./src/index.js main
[./src/parse-date.js] 1.27 KiB {main} [depth 1] [built]
cjs require ./parse-date [./src/index.js] 6:35-58
+ 212 hidden modules
我错过了什么? ...一定很简单,但我 运行 没有想法:(
项目可以found on GitHub方便审核(和git拉):)
要使 tree-shaking 工作,您必须将 TypeScript 配置为编译为 ES 模块而不是 CommonJS,并在 webpack 中启用生产模式:
- 在
tsconfig.json
中设置module: 'es2015'
- 在
webpack.config.js
中设置mode: 'production'
使用此设置,您将只有 1Kb 构建:
$ size-limit dist/bundle.js
Package size: 724 B
With all dependencies, minified and gzipped
这是您的存储库的补丁:
diff --git a/tsconfig.json b/tsconfig.json
index 42d6d90..b64255d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,7 +1,7 @@
{
"compilerOptions": {
/* Basic Options */
- "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
+ "target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
"allowJs": false, /* Allow javascript files to be compiled. */
diff --git a/webpack.config.js b/webpack.config.js
index 8ccbc94..1419137 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -3,7 +3,7 @@ const path = require('path');
const config = {
entry: './src/index.js',
- mode: 'development',
+ mode: 'production',
stats: 'verbose',
output: {
path: path.resolve(__dirname, 'dist'),
这是对 tree-shaking 对我有用的 date-fns 函数的修复,使用 Webpack 别名(最初提到 in the opened Github issue)
我从解决方案to make tree-shaking work for locales推导出解决方案。
- 在您的 webpack 配置旁边创建一个名为
date-fns-functions.js
的文件,您将在其中 re-export 您在项目中使用的函数,如下所示:
export { default as parseISO } from 'date-fns/parseISO';
export { default as formatDistanceToNow } from 'date-fns/formatDistanceToNow';
export { default as parse } from 'date-fns/parse';
...
- 然后,为您的 Webpack 配置添加一个别名:
resolve: {
alias: {
'date-fns$': require.resolve('./date-fns-functions.js')
}
},
在我的特殊情况下,使用 Nuxt.js 进行 Webpack 捆绑我在 nuxt.config.js 中添加了它:
extend (config, ctx) {
config.resolve.alias['date-fns$'] = require.resolve('./date-fns-functions.js');
...
}
每次从 date-fns
导入内容时,它会使用别名查找导入,避免完全导入整个库。
这解决了我的问题并大大减少了包的大小。
我无法理解 date-fns v.2 tree-shaking 功能的工作原理...
为了帮助我,我做了一个非常简单的项目:
date-fns 2.1.0
webpack 4.39.3
typescript 3.6.2
测试包含2个文件,一个作为"library",另一个作为运行的代码,就这么简单...
import ParseDate from './parse-date'
const parse = new ParseDate();
const result = parse.getExpirationDate({ months: 3 });
console.log(result);
但问题是,虽然我只要求使用 tree-shaking 使用 6 个库
import { addYears, addMonths, addWeeks, addDays, addHours, addMinutes } from 'date-fns';
来自他们的 docs:
// Without tree-shaking:
import format from 'date-fns/format'
import parse from 'date-fns/parse'
// With tree-shaking:
import { format, parse } from 'date-fns'
webpack 正在捆绑整个 date-fns 库,这是 2 个文件的结果,726Kb !!
> npm run build
> date_fns_test@1.0.0 build C:\Users\balexandre\date_fns_test
> tsc && webpack
Hash: 419a712549fc2309f21e
Version: webpack 4.39.3
Time: 820ms
Built at: 2019-09-09 17:27:36
Asset Size Chunks Chunk Names
bundle.js 726 KiB main [emitted] main
Entrypoint main = bundle.js
chunk {main} bundle.js (main) 441 KiB [entry] [rendered]
> ./src/index.js main
[./src/index.js] 410 bytes {main} [depth 0] [built]
single entry ./src/index.js main
[./src/parse-date.js] 1.27 KiB {main} [depth 1] [built]
cjs require ./parse-date [./src/index.js] 6:35-58
+ 212 hidden modules
我错过了什么? ...一定很简单,但我 运行 没有想法:(
项目可以found on GitHub方便审核(和git拉):)
要使 tree-shaking 工作,您必须将 TypeScript 配置为编译为 ES 模块而不是 CommonJS,并在 webpack 中启用生产模式:
- 在
tsconfig.json
中设置module: 'es2015'
- 在
webpack.config.js
中设置mode: 'production'
使用此设置,您将只有 1Kb 构建:
$ size-limit dist/bundle.js
Package size: 724 B
With all dependencies, minified and gzipped
这是您的存储库的补丁:
diff --git a/tsconfig.json b/tsconfig.json
index 42d6d90..b64255d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,7 +1,7 @@
{
"compilerOptions": {
/* Basic Options */
- "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
+ "target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
"allowJs": false, /* Allow javascript files to be compiled. */
diff --git a/webpack.config.js b/webpack.config.js
index 8ccbc94..1419137 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -3,7 +3,7 @@ const path = require('path');
const config = {
entry: './src/index.js',
- mode: 'development',
+ mode: 'production',
stats: 'verbose',
output: {
path: path.resolve(__dirname, 'dist'),
这是对 tree-shaking 对我有用的 date-fns 函数的修复,使用 Webpack 别名(最初提到 in the opened Github issue)
我从解决方案to make tree-shaking work for locales推导出解决方案。
- 在您的 webpack 配置旁边创建一个名为
date-fns-functions.js
的文件,您将在其中 re-export 您在项目中使用的函数,如下所示:
export { default as parseISO } from 'date-fns/parseISO';
export { default as formatDistanceToNow } from 'date-fns/formatDistanceToNow';
export { default as parse } from 'date-fns/parse';
...
- 然后,为您的 Webpack 配置添加一个别名:
resolve: {
alias: {
'date-fns$': require.resolve('./date-fns-functions.js')
}
},
在我的特殊情况下,使用 Nuxt.js 进行 Webpack 捆绑我在 nuxt.config.js 中添加了它:
extend (config, ctx) {
config.resolve.alias['date-fns$'] = require.resolve('./date-fns-functions.js');
...
}
每次从 date-fns
导入内容时,它会使用别名查找导入,避免完全导入整个库。
这解决了我的问题并大大减少了包的大小。