提问人:naknik 提问时间:1/13/2023 更新时间:4/28/2023 访问量:218
为多个项目中的通用功能创建打字稿库
Creating a typescript library for generic functionality in several projects
问:
我想导出几个类,有些是独立的,有些需要彼此,由一个命名空间包装,作为其他项目使用的模块。
所以我设置了一个 webpack 构建,将它们编译成一个缩小的 .js 文件和一个 .d.ts 文件,它们都被命名空间“Platform”包裹。
下面是我用于自定义事件的示例类:
namespace Platform {
export class GameEvent {
****code****
}
}
问题是,一旦我将它们包装在这个命名空间中,构建就会失败并出现以下错误:
./Utilities/GameEvent.ts 中的错误 模块构建失败(从 ../node_modules/ts-loader/index.js): 错误:TypeScript 没有发出 \Platform\src\Utilities\GameEvent.ts 的输出。 在 makeSourceMapAndFinish (\Platform\node_modules\ts-loader\dist\index.js:53:18) 在 successLoader (\Platform\node_modules\ts-loader\dist\index.js:40:5) 在 Object.loader (\Platform\node_modules\ts-loader\dist\index.js:23:5)
这是我的 tsconfig:
{
"compilerOptions": {
"target": "es6",
"module": "esnext",
"strict": true,
"noEmit": false,
"importHelpers": true,
"moduleResolution": "node",
"esModuleInterop": true,
"sourceMap": true,
"baseUrl": "./src",
"rootDir": "./src",
"outDir": "./types",
"emitDeclarationOnly": true,
"declaration": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"lib": [
"es6",
"dom"
],
"removeComments": true,
"typeRoots": [
"node_modules/@types",
"node_module/phaser/types"
],
"types": [
"phaser",
"jest"
]
},
"include": [
"src/**/*",
]
}
这是我的webpack.config.js:
const path = require("path");
const webpack = require('webpack');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const DeclarationBundlerPlugin = require('declaration-bundler');
const fs = require('fs');
const srcDir = path.resolve(__dirname, 'src');
const typesDir = path.resolve(__dirname, 'types');
function scanDirectory(dir) {
const fileArr = [];
fs.readdirSync(dir).forEach((file) => {
const filepath = path.join(dir, file);
if (fs.lstatSync(filepath).isDirectory()) {
fileArr.push(...scanDirectory(filepath));
} else if (/\.tsx?$/.test(file)) {
fileArr.push(path.resolve(filepath));
}
});
return fileArr;
}
const entryPoints = scanDirectory(srcDir);
const typeEntryPoints = scanDirectory(typesDir);
module.exports = {
mode: "production",
context: path.resolve(__dirname, 'src'),
entry: {
'platform': entryPoints
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: "[name].min.js",
},
externals: {
phaser: 'phaser',
},
module: {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
},
],
include: [path.resolve(__dirname, 'src')],
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
plugins: [
new CleanWebpackPlugin(),
new webpack.DefinePlugin({
'typeof SHADER_REQUIRE': JSON.stringify(false),
'typeof CANVAS_RENDERER': JSON.stringify(true),
'typeof WEBGL_RENDERER': JSON.stringify(true)
}),
new DeclarationBundlerPlugin({
entry: typeEntryPoints,
moduleName: 'Platform',
out: './platform.d.ts',
}),
],
performance: { hints: false },
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: true,
safari10: true,
mangle: true,
output: {
comments: false
}
}
})
]
}
};
这些是我的 devDependencies:
"@jest/globals": "^29.3.1",
"@declaration-bundler": "^1.0.1",
"@types/jest": "^29.2.5",
"before-build-webpack": "^0.2.13",
"clean-webpack-plugin": "^3.0.0",
"glob": "^8.0.3",
"html-webpack-plugin": "^5.3.1",
"jest": "^29.3.1",
"jest-canvas-mock": "^2.4.0",
"jest-environment-jsdom": "^29.3.1",
"terser-webpack-plugin": "^5.3.6",
"ts-jest": "^29.0.3",
"ts-loader": "^8.0.18",
"ts-node": "^10.9.1",
"typescript": "^4.9.4",
"webpack": "^5.28.0",
"webpack-cli": "^4.9.1"
我尝试只对每个没有命名空间的文件使用“导出默认类”,但是当我发布包并在另一个项目中使用它时,它无法将其识别为模块并且无法构建/测试。
我应该怎么做?
答:
好的,我想通了,不完全是我想要的,但它运行良好。
这是我的webpack.config.js:
const path = require("path");
const webpack = require('webpack');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const DtsBundleWebpack = require("dts-bundle-webpack");
const removeEmptyDirectories = require('remove-empty-directories');
const libPath = path.resolve(__dirname, 'lib');
module.exports = {
mode: "production",
context: path.resolve(__dirname, 'src'),
entry: {
'platform': "./platform.ts"
},
output: {
path: libPath,
filename: "[name].min.js",
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
plugins: [
new CleanWebpackPlugin(),
new webpack.DefinePlugin({
'typeof SHADER_REQUIRE': JSON.stringify(false),
'typeof CANVAS_RENDERER': JSON.stringify(true),
'typeof WEBGL_RENDERER': JSON.stringify(true)
}),
new DtsBundleWebpack({
name: "<lib name>",
main: "lib/platform.d.ts",
out: "platform.d.ts",
removeSource: true,
outputAsModuleFolder: true
}),
function () {
this.hooks.done.tap("Done", (stats) => {
removeEmptyDirectories(libPath);
});
}
],
performance: { hints: false },
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: true,
safari10: true,
mangle: true,
output: {
comments: false
}
}
})
]
}
};
我的文件结构是这样的:
其中,每个index.ts文件都有一个类文件的“export * from 'filename'”。
platform.ts文件导出所有模块
评论
这里还有另一个问题,可能不是你在这个例子中的问题,但另一个常见的原因是在 中设置为 true。Error: TypeScript emitted no output for _____.ts
noEmit
tsconfig.json
上一个:嵌套环境模块
下一个:Python 导入模块方法
评论