中文版在英文版之后。
NPM Publish Reference
Talking over NPM Publish
, it is unavoidable to go through the long evolution history of CommonJS
and AMD
into UMD
and finally ES Module
. However, we choose to leave it to further reading in References.
In short, we are supposed to publish ES Module
stated in module
field, for those projects able to recognize ES Module
; for other projects unable to do so, we are supposed to publish CommonJS
stated in main
; if we have browser support requirements, we are supposed to publish UMD
instead of CommonJS
or side by side.
Published directories
Here we provide a list of well-known javascript/typescript projects on Github, let’s take a look how they publish npm packages:
redux
:- adopts
Rollup
; - inside repository, places source code under
src
with nothing else published; - inside
npm
, publishes:src
;lib
(uncompressedCommonJS
, pointed bymain
);es
(uncompressed and compressedES Module
, pointed bymodule
);dist
(uncompressed and compressedUMD
, pointed byunpkg
);
- adopts
react-use
:- adopts
tsc
; - inside repository, places source code under
src
with nothing else published; - inside
npm
, publishes:lib
(uncompressedCommonJS
, pointed bymain
);esm
(uncompressedES Module
, pointed bymodule
);
- adopts
vue
:- adopts
Rollup
; - inside repository, places source code under
src
, along withdist
published; - inside
npm
, publishes:src
;dist
(containing uncompressed and compressedCommonJS
, uncompressed and compressedES Module
and uncompressed and compressedUMD
), withmain
pointing atCommonJS
,module
pointing atES Module
andunpkg
andjsdelivr
pointing atUMD
;
- adopts
react
:- adopts
Rollup
; - inside repository, places sources code under
src
of MonoRepo, with nothing else published; - inside
npm
, publishes:cjs
(uncompressed and compressedCommonJS
, pointed bymain
);umd
(uncompressed and compressedUMD
);
- adopts
angular
:- adopts internal tools;
- inside repository, places source code under
src
of MonoRepo, with nothing else published; - inside
npm
, publishes:bundles
(uncompressed and compressedUMD
, pointed bymain
);- various versions of
ES Module
(esm
vs.fesm
,ES5
vs.ES2015
,module
pointing atfesm5
);
react-router
:- adopts
Rollup
; - inside repository, places source code under
modules
of MonoRepo, with nothing else published; - inside
npm
, publishes:cjs
(uncompressed and compressedCommonJS
, pointed bymain
);esm
(uncompressedES Module
, pointed bymodule
);umd
(uncompressed and compressedUMD
);
- adopts
axios
:- adopts
Webpack
; - inside repository, places source code under
lib
, along withdist
published; - inside
npm
, publishes:lib
;dist
(uncompressed and compressedUMD
, pointed bymain
);
- adopts
material-ui
:- adopts
Rollup
forUMD
andBabel
forCommonJS
andES Module
; - inside repository, places source code under
src
of MonoRepo, with nothing else published; - inside
npm
, publishes:- root directory (uncompressed
CommonJS
, pointed bymain
); es
(uncompressedES Module
);esm
(uncompressedES Module
ofES5
, pointed bymodule
);umd
(uncompressed and compressedUMD
);
- root directory (uncompressed
- adopts
antd
:- adopts
Webpack
; - inside repository, places source code under
components
, with nothing else published; - inside
npm
, publishes:lib
(uncompressedCommonJS
, pointed bymain
);es
(uncompressedES Module
, pointed bymodule
);dist
(uncompressed and compressedUMD
, pointed byunpkg
);
- adopts
element-ui
:- adopts
Webpack
; - inside repository, places source code under
src
andpackages
, with nothing else published; - inside
npm
, publishes:lib
(single-file and multiple-fileCommonJS
, compressedUMD
,main
pointing atCommonJS
).
- adopts
unpkg
links of above mentioned projects can be found in References and package.json
has field repository
for repository info.
Recommendation
- Adopt
Rollup
, for fast compilation, smaller bundle size and clean and straightforward configuration and workflow; - Place source code under
src
orsrc
of MonoRepo; - Publish
UMD
、CommonJS
和ES Module
in separate directories, or in directories with common conventions (e.g.lib
forCommonJS
anddist
forUMD
); - Publish both uncompressed and compressed
UMD
(for development and production purpose); - Publish both uncompressed and compressed
ES Module
since popular browsers are powerful and smark enough; - Point
main
atCommonJS
orUMD
andmodule
atES Module
inpackage.json
.
BTW, typescript
projects will also publish .d.ts
files, which can benefit target users as well as IDEs a lot. Alternatively, you can write your own type definition files.
NPM 发布参考
说到 NPM Publish
,免不了去介绍 CommonJS
和 AMD
然后到 UMD
再到 ES Module
的历史,这边把详细介绍放在参考文献里。
简而言之我们需要,发布以 module
为入口的 ES Module
版本,供能识别 ES Module
的项目使用;发布以 main
为入口的 UMD
版本,供浏览器和不能识别 ES Module
的项目使用,如果不需要浏览器支持则可以只发布 CommonJS
版本。
发布目录
这边先罗列一下大家耳熟能详的一些项目的发布方式:
redux
:- 使用
Rollup
; - 仓库里,源代码在
src
,无其他发布内容; npm
里,发布:src
;lib
(非压缩的CommonJS
,main
);es
(非压缩和压缩的ES Module
,module
);dist
(非压缩和压缩的UMD
,unpkg
);
- 使用
react-use
:- 使用
tsc
; - 仓库里,源代码在
src
,无其他发布内容; npm
里,发布:lib
(非压缩的CommonJS
,main
);esm
(非压缩的ES Module
,module
);
- 使用
vue
:- 使用
Rollup
; - 仓库里,源代码在
src
,同时发布dist
; npm
里,发布:src
;dist
(非压缩和压缩的CommonJS
、非压缩和压缩的ES Module
、非压缩和压缩的UMD
),main
指向CommonJS
,module
指向ES Module
,unpkg
和jsdelivr
指向UMD
;
- 使用
react
:- 使用
Rollup
; - 仓库里,源代码在 MonoRepo 的
src
,无其他发布内容; npm
里,发布:cjs
(非压缩和压缩的CommonJS
,main
);umd
(非压缩和压缩的UMD
);
- 使用
angular
:- 使用内部工具;
- 仓库里,源代码在 MonoRepo 的
src
,无其他发布内容; npm
里,发布:bundles
(非压缩和压缩的UMD
,main
);- 多种
ES Module
(esm
和fesm
,ES5
和ES2015
,module
指向fesm5
);
react-router
:- 使用
Rollup
; - 仓库里,源代码在 MonoRepo 的
modules
,无其他发布内容; npm
里,发布:cjs
(非压缩和压缩的CommonJS
,main
);esm
(非压缩的ES Module
,module
);umd
(非压缩和压缩的UMD
);
- 使用
axios
:- 使用
Webpack
; - 仓库里,源代码在
lib
,同时发布dist
; npm
里,发布:lib
;dist
(非压缩和压缩的UMD
,main
);
- 使用
material-ui
:- 使用
Rollup
生成UMD
和Babel
生成CommonJS
和ES Module
; - 仓库里,源代码在 MonoRepo 的
src
,无其他发布内容; npm
里,发布:- 扁平目录(非压缩的
CommonJS
,main
); es
(非压缩的ES Module
);esm
(非压缩的ES5
的ES Module
,module
);umd
(非压缩和压缩的UMD
);
- 扁平目录(非压缩的
- 使用
antd
:- 使用
Webpack
; - 仓库里,源代码在
components
,无其他发布内容; npm
里,发布:lib
(非压缩的CommonJS
,main
);es
(非压缩的ES Module
,module
);dist
(非压缩和压缩的UMD
,unpkg
);
- 使用
element-ui
:- 使用
Webpack
; - 仓库里,源代码在
src
和packages
,无其他发布内容; npm
里,发布:lib
(整合和散装的非压缩的CommonJS
、压缩的UMD
),main
指向CommonJS
。
- 使用
以上项目都能在参考文献里找到 unpkg
的链接,然后在 package.json
里找到仓库。
推荐方案
- 使用
Rollup
,使得你的编译打包更快、体积更小(可以阅读参考文献),编译配置及流程清晰(一些项目整个流程非常繁冗复杂); - 源代码放在
src
或者 MonoRepo 的src
; - 单独为
UMD
、CommonJS
和ES Module
建立发布目录,或者使用有习惯用途的目录命名(CommonJS
放在lib
,UMD
放在dist
); UMD
提供非压缩和压缩两个版本(供开发和生产使用);ES Module
最好也提供压缩版本,供浏览器使用;package.json
的main
指向CommonJS
或UMD
,module
指向ES Module
。
另外说一下,typescript
的项目会发布 .d.ts
的文件,可以给 IDE 以及开发者提供便利。不过也可以自行编写类型定义文件。
References:
- NPM official documentation: packages-and-modules, npm-package
- JavaScript module system, CommonJS, Asynchronous Module Definition, IIFE
- Popular repositories: redux, react-use, vue, react, angular, react-router, axios, material-ui, antd, element-ui
- Angular Flattening of ES Modules
- The cost of small modules (Rollup recommendation)