ts-demo-npm-cjs
.gitignore
.npmignore
package.json
dependencies
与 devDependencies
package.json
的更多信息tsconfig.json
index.ts
index_test.ts
本章介绍如何使用 TypeScript 为 npm 包管理器创建基于 CommonJS 模块格式的包。
GitHub 仓库:ts-demo-npm-cjs
在本章中,我们将探索 代码仓库 ts-demo-npm-cjs
,它可以在 GitHub 上下载。(我特意没有将其作为包发布到 npm。)
您应该大致熟悉
CommonJS 模块 – 一种起源于服务器端 JavaScript 并为其设计的模块格式。它因服务器端 JavaScript 平台 Node.js 而流行。CommonJS 模块先于 JavaScript 内置的 ECMAScript 模块,并且仍然被工具(IDE、构建工具等)广泛使用和支持。
TypeScript 的模块 – 其语法基于 ECMAScript 模块。但是,它们通常被编译为 CommonJS 模块。
npm 包 – 通过 npm 包管理器安装的包含文件的目录。它们可以包含 CommonJS 模块、ECMAScript 模块和各种其他文件。
在本章中,我们使用 TypeScript 当前最支持的内容
.js
的 CommonJS 模块。特别是在 Node.js 上,TypeScript 当前并不真正支持 ECMAScript 模块和 .js
以外的文件扩展名。
ts-demo-npm-cjs
这就是代码仓库 ts-demo-npm-cjs
的结构
ts-demo-npm-cjs/
.gitignore
.npmignore
dist/ (created on demand)
package.json
ts/
src/
index.ts
test/
index_test.ts
tsconfig.json
除了包的 package.json
之外,该仓库还包含
ts/src/index.ts
:包的实际代码ts/test/index_test.ts
:index.ts
的测试tsconfig.json
:TypeScript 编译器的配置数据package.json
包含用于编译的脚本
ts/
(TypeScript 代码)dist/
(CommonJS 模块;该目录在代码仓库中尚不存在)这是放置两个 TypeScript 文件的编译结果的地方
ts/src/index.ts --> dist/src/index.js
ts/test/index_test.ts --> dist/test/index_test.js
.gitignore
此文件列出了我们不想提交到 git 的目录
node_modules/
dist/
说明
node_modules/
是通过 npm install
设置的。dist/
中的文件是由 TypeScript 编译器创建的(稍后会详细介绍)。.npmignore
当涉及到哪些文件应该和不应该上传到 npm 注册表时,我们与 git 的需求不同。因此,除了 .gitignore
之外,我们还需要文件 .npmignore
ts/
这两个区别是
dist/
)。ts/
)。请注意,npm 默认忽略目录 node_modules/
。
package.json
package.json
如下所示
{
···
"type": "commonjs",
"main": "./dist/src/index.js",
"types": "./dist/src/index.d.ts",
"scripts": {
"clean": "shx rm -rf dist/*",
"build": "tsc",
"watch": "tsc --watch",
"test": "mocha --ui qunit",
"testall": "mocha --ui qunit dist/test",
"prepack": "npm run clean && npm run build"
},
"// devDependencies": {
"@types/node": "Needed for unit test assertions (assert.equal() etc.)",
"shx": "Needed for development-time package.json scripts"
},
"devDependencies": {
"@types/lodash": "···",
"@types/mocha": "···",
"@types/node": "···",
"mocha": "···",
"shx": "···"
},
"dependencies": {
"lodash": "···"
}
}
让我们来看看这些属性
type
:值 "commonjs"
表示 .js
文件被解释为 CommonJS 模块。main
:如果有所谓的*裸导入*,只提及当前包的名称,那么这就是将要导入的模块。types
指向一个包含当前包所有类型定义的声明文件。接下来的两个小节涵盖了其余的属性。
属性 scripts
定义了可以通过 npm run
调用的各种命令。例如,脚本 clean
通过 npm run clean
调用。之前的 package.json
包含以下脚本
clean
使用 跨平台包 shx
通过其实现 Unix shell 命令 rm
来删除编译结果。shx
支持各种 shell 命令,其优点是不需要为我们可能要使用的每个命令都安装一个单独的包。
build
和 watch
使用 TypeScript 编译器 tsc
根据 tsconfig.json
编译 TypeScript 文件。tsc
必须全局或本地(在当前包内)安装,通常通过 npm 包 typescript
安装。
test
和 testall
使用 单元测试框架 Mocha 来运行一个测试或所有测试。
prepack
:此脚本在打包 tarball 之前运行(由于 npm pack
、npm publish
或从 git 安装)。
请注意,当我们使用 IDE 时,我们不需要脚本 build
和 watch
,因为我们可以让 IDE 构建工件。但是脚本 prepack
需要它们。
dependencies
与 devDependencies
dependencies
应该只包含导入包时需要的包。这排除了用于运行测试等的包。
名称以 @types/
开头的包为没有类型定义的包提供 TypeScript 类型定义。没有前者,我们就不能使用后者。这些是正常的依赖项还是开发依赖项?这取决于
如果我们包的类型定义引用了另一个包中的类型定义,那么该包就是一个正常的依赖项。
否则,该包只在开发期间需要,是一个开发依赖项。
package.json
的更多信息package.json
的 npm 文档 解释了该文件的各种属性。scripts
的 npm 文档 解释了 package.json
属性 scripts
。tsconfig.json
{
"compilerOptions": {
"rootDir": "ts",
"outDir": "dist",
"target": "es2019",
"lib": [
"es2019"
],
"module": "commonjs",
"esModuleInterop": true,
"strict": true,
"declaration": true,
"sourceMap": true
}
}
rootDir
:我们的 TypeScript 文件在哪里?
outDir
:编译结果应该放在哪里?
target
:目标 ECMAScript 版本是什么?如果 TypeScript 代码使用了目标版本不支持的特性,那么它将被编译成只使用支持特性的等效代码。
lib
:TypeScript 应该知道哪些平台特性?可能性包括 ECMAScript 标准库和浏览器的 DOM。Node.js API 的支持方式不同,通过包 @types/node
支持。
module
:指定编译输出的格式。
其余选项由 tsconfig.json
的官方文档 解释。
index.ts
此文件提供了包的实际功能
import endsWith from 'lodash/endsWith';
function removeSuffix(str: string, suffix: string) {
export if (!endsWith(str, suffix)) {
new Error(JSON.stringify(suffix)} + ' is not a suffix of ' +
throw JSON.stringify(str));
}.slice(0, -suffix.length);
return str }
它使用 库 Lodash 的函数 endsWith()
。这就是为什么 Lodash 是一个正常的依赖项——它在运行时是必需的。
index_test.ts
此文件包含 index.ts
的单元测试
import { strict as assert } from 'assert';
import { removeSuffix } from '../src/index';
test('removeSuffix()', () => {
.equal(
assertremoveSuffix('myfile.txt', '.txt'),
'myfile');
.throws(() => removeSuffix('myfile.txt', 'abc'));
assert; })
我们可以像这样运行测试
npm t dist/test/index_test.js
t
是 npm 命令 test
的缩写。test
是 run test
的缩写(它运行 package.json
中的脚本 test
)。如您所见,我们正在运行测试的编译版本(在目录 dist/
中),而不是 TypeScript 代码。
有关单元测试框架 Mocha 的更多信息,请参阅 其主页。