Skip to content

Commit 5898c46

Browse files
committed
Remove ESM generated code
## Details - This PR basically reverts PR #32 because this is hell. More about this in **Why???** section below. - Only generate CommonJS code in `lib/` instead of both ESM and CommonJS code. - Remove Babel stuff and rely on `tsc` to generate CommonJS code and TypeScript declaration files in `lib/`. ## Why??? - Because this is hell. Totally hell. - Before this PR, rtp.js can not be used in TypeScript projects that use Webpack to generate a bundled JS file. Why? Because Webpack assumes that everything is CommonJS but then it miserably fails to locate/resolve '.cjs' files. - If we have '.ts' files in `src/` folder, then `tsc` will generate 'js' files rather than '.mjs' files, and that means problems with loaders/bundlers that assume that '.js' files contain CommonJS and then they fail to process them because those '.js' files contain 'import/export' rather than 'require/module.exports'. - And if we have '.mts' files in `src` then `tsc` will generate `.mjs` with ESM code but it's literally impossible to have another `tsconfig-cjs.json` file to make `tsc` generate CommonJS code. - So then we moved to Babel to generate ESM and CJS code (see PR #32), and we have to include tricks to replace the extension in the `import` and `require()` calls in the generated ESM and CJS code in `lib/`, which is terrible. But then Babel also generates `.js.map` files that reference a `.mts` file in `lib/` folder which obviously doesn't exist. - And another problem is that Babel only generates JavaScript code so we still need to use `tsc` to generate TypeScript declaration files and, since we have '.mts' files in `src/`, those declaration files have `d.mts` extension. But they many text editors and TypeScript consumers asusme that declaraion files must be '.d.ts' only. And if we rename their extension then we have also to munge generated `.mjs` (ESM) and `.cjs` files in `lib/` because those files contain special commented mapping lines that reference the declaration file (with '.d.mts'). - And then it also happens that in CommonJS importing a file without extendion is ok, but in ESM you must write `import foo from './foo.ts'` rather than `from './foo'`. So here another needed rewrite in generated `lib/` code. - etc etc etc, and **trust me**, more etc etc etc. I've tried EVERYTHING, much more than what I've told here. ## Conclusion - It's impossible to generate ESM and CJS file in a proper way because it entirely affects the way the TypeScript code must be written, and it includes whether to use `.ts` or `.mts` extension in source files, whether to import internal files with or without extension, and `tsconfig.json` doesn't expose options enough to cover all cases we need when generating ESM or CJS code. I've checked them all, and the same with Babel. - My conclusion is that, if you want to publish a library in ESM format, you only generate ESM code ('.mjs' files) from TypeScript '.mts' files. But you cannot generate **also** CJS files. And the other way around.
1 parent 9d94239 commit 5898c46

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+4173
-7445
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ npm install rtp.js
7878
// Using ESM:
7979
import { packets as rtpJsPackets, utils as rtpJsUtils } from 'rtp.js';
8080

81-
// Using CJS:
81+
// Using CommonJS:
8282
const { packets: rtpJsPackets, utils: rtpJsUtils } = require('rtp.js');
8383

8484
const { RtpPacket /* etc. */ } = rtpJsPackets;

babel.config-cjs.mjs

Lines changed: 0 additions & 34 deletions
This file was deleted.

babel.config-esm.mjs

Lines changed: 0 additions & 34 deletions
This file was deleted.

babel.config-jest.cjs

Lines changed: 0 additions & 24 deletions
This file was deleted.

eslint.config.mjs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,21 +107,21 @@ const config = tsEslint.config(
107107
yoda: 2,
108108
},
109109
},
110-
// NOTE: We need to apply this only to .mts source files (and not to .mjs
110+
// NOTE: We need to apply this only to .ts source files (and not to .mjs
111111
// files).
112112
...tsEslint.configs.recommendedTypeChecked.map(item => ({
113113
...item,
114-
files: ['src/**/*.mts'],
114+
files: ['src/**/*.ts'],
115115
})),
116-
// NOTE: We need to apply this only to .mts source files (and not to .mjs
116+
// NOTE: We need to apply this only to .ts source files (and not to .mjs
117117
// files).
118118
...tsEslint.configs.stylisticTypeChecked.map(item => ({
119119
...item,
120-
files: ['src/**/*.mts'],
120+
files: ['src/**/*.ts'],
121121
})),
122122
{
123-
name: '.mts source files',
124-
files: ['src/**/*.mts'],
123+
name: '.ts source files',
124+
files: ['src/**/*.ts'],
125125
languageOptions: {
126126
parserOptions: {
127127
projectService: true,
@@ -165,9 +165,9 @@ const config = tsEslint.config(
165165
},
166166
},
167167
{
168-
name: '.mts test files',
168+
name: '.ts test files',
169169
...jestEslint.configs['flat/recommended'],
170-
files: ['src/test/**/*.mts'],
170+
files: ['src/test/**/*.ts'],
171171
rules: {
172172
...jestEslint.configs['flat/recommended'].rules,
173173
'jest/no-disabled-tests': 2,

jest.config.mjs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
11
const config = {
22
verbose: true,
33
testEnvironment: 'node',
4-
testRegex: 'src/test/.*.test.mts',
5-
// Make Jest consider .mts files as if they were ES modules.
6-
moduleFileExtensions: ['mts', 'mjs', 'js', 'ts'],
4+
testRegex: 'src/test/.*.test.ts',
75
transform: {
8-
'^.+\\.mts?$': [
9-
'babel-jest',
10-
{
11-
// We need special Babel settings for Jest plust we need it to be in
12-
// a CJS configuration file, otherwise old versions of Node will fail
13-
// to run Jest.
14-
configFile: './babel.config-jest.cjs',
15-
},
16-
],
6+
'^.+\\.ts?$': ['ts-jest'],
177
},
18-
coveragePathIgnorePatterns: ['src/Logger.mts', 'src/test'],
8+
coveragePathIgnorePatterns: ['src/Logger.ts', 'src/test'],
199
cacheDirectory: '.cache/jest',
2010
};
2111

npm-scripts.mjs

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ const RELEASE_BRANCH = 'master';
77

88
// Paths for ESLint to check. Converted to string for convenience.
99
const ESLINT_PATHS = [
10-
'babel.config-cjs.mjs',
11-
'babel.config-esm.mjs',
12-
'babel.config-jest.cjs',
1310
'eslint.config.mjs',
1411
'jest.config.mjs',
1512
'npm-scripts.mjs',
@@ -25,9 +22,6 @@ const ESLINT_IGNORE_PATTERN_ARGS = []
2522
// Paths for Prettier to check/write. Converted to string for convenience.
2623
const PRETTIER_PATHS = [
2724
'README.md',
28-
'babel.config-cjs.mjs',
29-
'babel.config-esm.mjs',
30-
'babel.config-jest.cjs',
3125
'eslint.config.mjs',
3226
'jest.config.mjs',
3327
'npm-scripts.mjs',
@@ -161,50 +155,20 @@ function buildTypescript() {
161155

162156
deleteLib();
163157

164-
// Generate .mjs ESM files in lib/.
165-
executeCmd(
166-
'babel ./src --config-file "./babel.config-esm.mjs" --out-dir "./lib" --ignore "./src/test/**" --extensions .mts --out-file-extension .mjs --source-maps true'
167-
);
168-
169-
// Generate .cjs CJS files in lib/.
170-
executeCmd(
171-
'babel ./src --config-file "./babel.config-cjs.mjs" --out-dir "./lib" --ignore "./src/test/**" --extensions .mts --out-file-extension .cjs --source-maps true'
172-
);
173-
174-
// Generate .d.mts TypeScript declaration files in lib/.
158+
// Generate .js CommonJS code and .d.ts TypeScript declaration files in lib/.
175159
executeCmd('tsc');
176160

177-
// Delete generated TypeScript declaration files in lib/test/ because we don't
178-
// want to expose them.
161+
// Delete generated lib/test because we don't to expose them in the published
162+
// library.
179163
fs.rmSync('lib/test', { recursive: true, force: true });
180164
}
181165

182166
async function watchTypescript() {
183167
logInfo('watchTypescript()');
184168

185-
// NOTE: Load dep on demand since it's a devDependency.
186-
const { concurrently } = await import('concurrently');
187-
188169
deleteLib();
189170

190-
concurrently([
191-
// Generate .mjs ESM files in lib/ and watch for changes.
192-
{
193-
name: 'babel ESM',
194-
command:
195-
'babel ./src --config-file "./babel.config-esm.mjs" --out-dir "./lib" --ignore "./src/test/**" --extensions .mts --out-file-extension .mjs --source-maps true --watch',
196-
raw: true,
197-
},
198-
// Generate .cjs CJS files in lib/ and watch for changes.
199-
{
200-
name: 'babel CJS',
201-
command:
202-
'babel ./src --config-file "./babel.config-cjs.mjs" --out-dir "./lib" --ignore "./src/test/**" --extensions .mts --out-file-extension .cjs --source-maps true --watch',
203-
raw: true,
204-
},
205-
// Generate .d.mts TypeScript declaration files in lib/ and watch for changes.
206-
{ name: 'tsc', command: 'tsc --watch', prefixColors: 'auto', raw: true },
207-
]);
171+
executeCmd('tsc --watch');
208172
}
209173

210174
function lint() {

0 commit comments

Comments
 (0)