我想把我最常用的通用函数(typescript)集中在一个Util包中,这样我就可以在我的项目中重用它。结果比预期的要困难。这个包不会被发布,所以我真的只对ESM感兴趣。
我可以用一个普通的js-package来完成这个任务,但是现在我把它转换成TS,我遇到了一些问题。
我的问题是,如何从一个外部包导入?我使用各种Lodash函数。但Rollup抱怨它们不存在,和/或必须导出以及。
我已经包含了我放入这个库中的第一个函数,我对TS很陌生,所以不要太在意。-)
[!] RollupError: "now" is not exported by "../../node_modules/.pnpm/lodash@4.17.21/node_modules/lodash/lodash.js", imported by "out-tsc/src/createUid.js".
https://rollupjs.org/troubleshooting/#error-name-is-not-exported-by-module
out-tsc/src/createUid.js (1:9)
1: import { now, random, padStart } from "lodash";
^
这是我最新的设置,经历了许多许多变化:
- 配置 *
- 包. json**
{
"name": "@vexna/util",
"version": "1.0.0",
"description": "Generic utilities, uses lodash",
"private": true,
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"sideEffects": false,
"scripts": {
"build": "rimraf dist && tsc && rollup -c rollup.config.js",
"test": "node test/spec",
"pretest": "npm run build"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.20.12",
"@babel/preset-env": "^7.20.2",
"@open-wc/building-rollup": "^2.2.1",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-node-resolve": "^15.0.1",
"@types/lodash": "^4.14.191",
"deepmerge": "^4.3.0",
"lodash": "^4.17.21",
"rimraf": "^4.1.2",
"rollup": "^3.12.1",
"typescript": "^4.9.5"
},
"peerDependencies": {
"lodash": "^4.17.21"
},
"files": [
"dist"
]
}
- 系统配置json**
{
"compilerOptions": {
"target": "es2018",
"module": "esnext",
"moduleResolution": "node",
"noEmitOnError": true,
"lib": ["es2017"],
"strict": true,
"esModuleInterop": false,
"outDir": "out-tsc",
"rootDir": "./",
"skipLibCheck": true,
"declaration": true,
"allowSyntheticDefaultImports": true
},
"include": ["./src/**/*.ts"]
}
- 汇总配置js**
import merge from 'deepmerge';
import { createBasicConfig } from '@open-wc/building-rollup';
const baseConfig = createBasicConfig();
export default merge(baseConfig, {
input: ['./out-tsc/src/index.js'],
output: {
format: "esm",
exports: "named",
dir: 'dist',
},
external: ['loadash'],
});
- .巴伯尔中心*
{
"presets": [["@babel/env", { "modules": false }]]
}
- 密码 *
我将代码组织如下:
/src
/src/index.ts
/src/createUid.ts
createUid是我放入这个库中的第一个函数,我想把每个函数都放到它自己的文件中(但是如果它们必须都放在一个文件中,那也可以)。
- 创建用户ID. ts**
import { now, random, padStart } from "lodash"
/**
* Return a 16-digit unique integer based on the current time (ms) appended
* with a three-digit random or provided number ("counter").
*
* The id is an integer and consists of two parts:
* 1) The number of miliseconds is a 13-digit number
* 2) Appended with a three digit number, that is either:
* a) a left-padded number, if provided to the function
* b) a random numer
*
* 1675246953915 February 1st, 2023 (today)
* 9999999999999 November 20th, 2286
* 9007199254740 June 5th, 2255
* 9007199254740991 Max. safe integer
*
* Note:
* - This function won't work after November, 2286.
* If it is still in use then consider adding two instead of three digits,
* or use a bigint.
*
*/
const createUid = (counter?: number): (number|undefined) => {
let p1 = now() // ms
let p2 = ""
if (counter == undefined) {
p2 = padStart(random(0,999).toString(), 3, '0')
} else if (isNaN(counter)) {
p2 = padStart(random(0,999).toString(), 3, '0')
} else {
let carry = 0
if (counter > 999) {
counter = counter % 1000
carry = Math.trunc(counter / 1000)
}
p2 = padStart(counter.toString(),3,'0')
if (carry > 0) {
p1 += carry
}
}
// Create the integer
const retVal = parseInt(`${p1}${p2}`)
// Check if safe
if (!Number.isSafeInteger(retVal)) {
console.error(`Generated id is larger than safe integer ${Number.MAX_SAFE_INTEGER}.`)
return
}
return retVal
}
export { createUid }
- 索引. ts**
export { createUid } from './createUid'
1条答案
按热度按时间j8ag8udp1#
我发现了两个三个可能的工作场景:
1.使用TSdx,用于TypeScript包开发的零配置CLI。https://tsdx.io/
1.使用lodash-es代替(但是注意链在lodash-es中不起作用!)。解释如下。但是当这个库导入到另一个库中并在那里测试时,仍然会产生Jest错误。
1.使用
vitest
代替。Vitest与Jest api很大程度上兼容。安装Vitest后,一切都很简单,无需任何配置。唯一要做的是将import { assert, expect, test } from 'vitest'
添加到您的测试中。如果您刚刚开始,并且只有简单的测试,它们可以在没有任何更改的情况下工作(YMMV)。此外,**lodash和lodash-es都工作正常。一个更好的答案是使用"普通" lodash的场景,或者解释为什么lodash-es实际上是一个好东西。从我在各种帖子中读到的,lodash-es有几个缺点(导致更大的捆绑包大小,链不起作用)。
这是一个工作设置(我认为)合理的默认值。这个库是供内部使用的,我运行节点18,所以我在这里使用一个高目标版本。
输出已经完全外部化了lodash,所以非常小的包!作为预防措施,我添加了"lodash":"^4.17.21"到"peerDependencies"。这有点奇怪,因为它与devDependencies(使用-es)不匹配,但这看起来很好。YMMV。
在库代码中,可以导入lodash函数,如下所示:
使用此库的项目必须具有lodash,并且可以按如下方式导入: