My goal is to export multiple classes, some independent and others interdependent, encapsulated within a single namespace, in the form of a module for external project utilization.
To achieve this, I have configured a webpack build to compile these classes into one minified .js file and one .d.ts file, all enveloped by the namespace "Platform".
Below is an example of the custom events class used:
namespace Platform {
export class GameEvent {
****code****
}
}
The issue arises when I encase them in the namespace; the build fails with the following error:
ERROR in ./Utilities/GameEvent.ts Module build failed (from ../node_modules/ts-loader/index.js): Error: TypeScript emitted no output for \Platform\src\Utilities\GameEvent.ts. at makeSourceMapAndFinish (\Platform\node_modules\ts-loader\dist\index.js:53:18) at successLoader (\Platform\node_modules\ts-loader\dist\index.js:40:5) at Object.loader (\Platform\node_modules\ts-loader\dist\index.js:23:5)
Here is my 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/**/*",
]
}
Here is my 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
}
}
})
]
}
};
These are my 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"
I attempted using "export default class" individually for each file without the namespace, but upon publishing the package and utilizing it in another project, it fails to recognize as a module and subsequently fails during build/test processes.
Looking for guidance on how to approach this effectively.