使用不同的浏览器和 Node.js 实现将 Javascript 库作为 ES6 模块发出
Emit a Javascript library as an ES6 module with different browser and Node.js implementations
创建 ES6 库的最佳方法是什么,例如my-es6-crypto-lib
,在浏览器和Node.js中都可以使用,但每个平台的实现方式不同?
(例如 Node.js 实现使用内置的 crypto
模块以获得更好的性能。)
ES6 模块使用:
import { sha256 } from 'my-es6-crypto-lib'
let digest = sha256('abc')
console.log(digest)
或Node.js式要求:
let sha256 = require('my-es6-crypto-lib')
let digest = sha256('abc')
console.log(digest)
my-es6-crypto-lib
的 package.json
将包括:
{
"name": "my-es6-crypto-lib",
"main": "transpiled-to-commonjs/node.js",
"module": "es6-module/node.js",
"browser": "es6-module/browser.js",
...
}
- Node.js会按照
main
键解析CommonJS模块
- 能够使用 ES6 模块的工具(如 transpiler/bundling 工具)遵循
module
键。
- 使用 ES6 模块并为浏览器捆绑它们的工具(例如 rollup-plugin-node-resolve)将遵循
browser
键。
Node.js 的实际实现类似于:(transpiled-to-commonjs/node.js
)
// built-in module, faster than the pure Javascript implementation
let createHash = require('crypto')
export function sha256 (message) {
return createHash('sha256').update(message).digest('hex')
}
虽然浏览器实现看起来像:(es6-module/browser.js
)
// a javascript-only implementation available at es6-module/hashFunctions.js
import { sha256 } from './hashFunctions'
export function sha256 (message) {
// slightly different API than the native module
return sha256(message, 'hex')
}
注意,每个函数在每个平台上的实现是不同的,但是两个sha256
方法都有相同的参数message
和return一个字符串。
构造我的 ES6 模块以提供这些实现的最佳方式是什么?有没有 javascript 库可以做到这一点?
理想情况下:
- 未使用的实现应该可以进行 tree shaking,并且
- 不应使用运行时检查来确定当前环境。
(我也开了一个GitHub issue for Rollup →)
过了一段时间,我现在认为最好的方法实际上是为每个环境导出不同的功能。
In the past, complex javascript libraries have used solutions like Browserify to bundle a version of their application for the browser. Most of these solutions work by allowing library developers to extensively configure and manually override various dependencies with respective browser versions.
For example, where a Node.js application might use Node.js' built-in crypto module, a browser version would need to fall back to a polyfill-like alternative dependency like crypto-browserify.
With es6, this customization and configuration is no longer necessary. Your library can now export different functionality for different consumers. While browser consumers may import a native JavaScript crypto implementation which your library exports, Node.js users can choose to import a different, faster implementation which your library exports.
...
中通过示例进行了深入解释
创建 ES6 库的最佳方法是什么,例如my-es6-crypto-lib
,在浏览器和Node.js中都可以使用,但每个平台的实现方式不同?
(例如 Node.js 实现使用内置的 crypto
模块以获得更好的性能。)
ES6 模块使用:
import { sha256 } from 'my-es6-crypto-lib'
let digest = sha256('abc')
console.log(digest)
或Node.js式要求:
let sha256 = require('my-es6-crypto-lib')
let digest = sha256('abc')
console.log(digest)
my-es6-crypto-lib
的 package.json
将包括:
{
"name": "my-es6-crypto-lib",
"main": "transpiled-to-commonjs/node.js",
"module": "es6-module/node.js",
"browser": "es6-module/browser.js",
...
}
- Node.js会按照
main
键解析CommonJS模块 - 能够使用 ES6 模块的工具(如 transpiler/bundling 工具)遵循
module
键。 - 使用 ES6 模块并为浏览器捆绑它们的工具(例如 rollup-plugin-node-resolve)将遵循
browser
键。
Node.js 的实际实现类似于:(transpiled-to-commonjs/node.js
)
// built-in module, faster than the pure Javascript implementation
let createHash = require('crypto')
export function sha256 (message) {
return createHash('sha256').update(message).digest('hex')
}
虽然浏览器实现看起来像:(es6-module/browser.js
)
// a javascript-only implementation available at es6-module/hashFunctions.js
import { sha256 } from './hashFunctions'
export function sha256 (message) {
// slightly different API than the native module
return sha256(message, 'hex')
}
注意,每个函数在每个平台上的实现是不同的,但是两个sha256
方法都有相同的参数message
和return一个字符串。
构造我的 ES6 模块以提供这些实现的最佳方式是什么?有没有 javascript 库可以做到这一点?
理想情况下:
- 未使用的实现应该可以进行 tree shaking,并且
- 不应使用运行时检查来确定当前环境。
(我也开了一个GitHub issue for Rollup →)
过了一段时间,我现在认为最好的方法实际上是为每个环境导出不同的功能。
中通过示例进行了深入解释In the past, complex javascript libraries have used solutions like Browserify to bundle a version of their application for the browser. Most of these solutions work by allowing library developers to extensively configure and manually override various dependencies with respective browser versions.
For example, where a Node.js application might use Node.js' built-in crypto module, a browser version would need to fall back to a polyfill-like alternative dependency like crypto-browserify.
With es6, this customization and configuration is no longer necessary. Your library can now export different functionality for different consumers. While browser consumers may import a native JavaScript crypto implementation which your library exports, Node.js users can choose to import a different, faster implementation which your library exports.
...