[使用lodash-es,我们可以像这样挑选模块:import drop from 'lodash/drop';
这样,只有drop
被使用,而没有别的。
我如何通过汇总实现相同的目的?
我正在配置一个react&Typescript ui库,以在两个create-react-app项目中使用。我了解到,使用esm最适合我的用例,这是通过Rollup实现树状握手的最有效方式。但是,当我使用我的库时,我是这样导入的:import { someComponent }from 'my-ui-library';
是否像上面的cherry-pick方法那样单独选出someComponent
。语法有关系吗?
这里是我的rollup.config.js
:
import babel from 'rollup-plugin-babel';
import resolve from '@rollup/plugin-node-resolve';
import typescript from 'rollup-plugin-typescript2';
import svgr from '@svgr/rollup';
import url from '@rollup/plugin-url';
import json from '@rollup/plugin-json';
import external from 'rollup-plugin-peer-deps-external';
import includePaths from 'rollup-plugin-includepaths';
const pkg = require('./package.json');
export default {
cache: false,
input: 'src/index.ts',
output: [{ file: pkg.module, format: 'esm' }],
treeshake: true,
plugins: [
external({
preferBuiltins: false,
}),
babel({
exclude: /node_modules/,
plugins: ['external-helpers'],
externalHelpers: true, // Exclude babel helpers.
}),
json(),
resolve(),
svgr({
ref: true,
svgo: false,
}),
typescript({
clean: true,
typescript: require('typescript'),
}),
url(),
includePaths({
paths: ['src'],
}),
],
};
摇晃ESM软件包时似乎有一些陷阱。第一个问题是摇树仅在生产中有效,第二个问题是package.json
必须包含sideEffects: false
属性。不幸的是,在开发中,摇树仍会导入整个库以检索命名的导出。单击here有关webpack摇树的更多信息。
例如(正在开发中:import screenshot exmaple] >>
在上面的示例中,我正在导入名为defaultLayoutCommands
的命名导出;但是,即使webpack正在使用esm
文件,它仍然显示所有库都已导入。但是,如果我分离文件并直接导入,则显示的导入大小较小。在生产中,此should
defaultLayoutCommands
,就像第二个导入示例一样。就是说,摇树仅适用于webpack AND ESM。[使用CJS / UMD / AMD时,摇树将不起作用。相反,您必须将所有导出内容合并到一个类/对象(例如exports
对象)。然后使用ES6解构,可以使用该方法。
例如,lodash在单个文件中具有所有功能,例如:
function throttle(func, wait, options) { var leading = true, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } if (isObject(options)) { leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing }); }
然后将该功能作为方法附加到对象:
lodash.add = add; lodash.attempt = attempt; lodash.camelCase = camelCase; ... lodash.throttle = throttle; lodash.thru = thru; lodash.toArray = toArray; ...etc
然后使用IIFE导出
lodash
对象。这样做的好处是,您可以一次要求多个命名的导入:
const { get, debounce, isEmpty } = require("lodash");
缺点是您需要整个lodash对象。因此,要解决此问题,他们有单独的文件(和/或npm包!!!),以将导入限制为所需的内容。因此,它们在根包文件夹中包括了这样的其他文件:
...js get.js debounce.js isEmpty.js ...js
但是,这样做的缺点是您现在将具有三个导入:
const get = require("lodash/get"); const debounce = require("lodash/debounce"); const isEmpty = require("lodash/isEmpty");
但是!您的总体进口尺寸会更小...但是,包装尺寸会更大!因此,为了缓解这种情况,他们将一些流行的方法分解为各自独立的程序包:lodash.get,l odash.debounce和lodash.isEmpty!
因此,总之,如果您不打算使用CJS / UMD / AMD(就像lodash一样),那么在使用webpack
和 [[client中的ESM软件包。但是,如果要包括其他内部版本以实现更高的兼容性,则必须创建具有不同inputs
和不同outputs
的汇总配置数组。例如:const resolutions = {
globals: {
react: "React",
"react-is": "reactIs",
},
exports: "named",
};
export default [
{
input: "./src/index.js", // this transforms the entire source
output: [
{
file: pkg.main,
format: "cjs",
...resolutions,
},
{
file: pkg.fallback,
format: "umd",
name: "My-Example-Library",
...resolutions,
},
{
file: pkg.module,
format: "esm",
...resolutions,
},
],
...etc
},
{
input: "./src/components/example.js", // this transforms just an "example.js" file and ouputs to a "dist/example.[build].js" file
output: [
{
file: "dist/example.cjs.js,
format: "cjs",
...resolutions,
},
{
file: dist/example.umd.js,
format: "umd",
name: "My-Example",
...resolutions,
},
],
...etc
}
]
有关不同构建的用例的更多信息,请参见here。>>