Skip to content

Commit 97f4ecf

Browse files
authored
Cleanup raw and dist-raw directories (#1717)
* add notes and todo list * safely repeating changes from add-cjs-loader-resolve to remember what I did and filter any WIP mess I may have forgotten about * more sync * fix downloaded artifacts * sync * sync * sync * sync * cleanup * sync node-internal-modules-cjs-loader-old.js with raw * sync internal/modules/package_json_reader with new naming convention * sync node-internal-modules-cjs-loader; rename back to old name * sync * more sync of filenames * sync node-internal-errors * lint-fix * fix * fix * further alignment * fix * fix * upgrade v8-compile-cache-lib to get rid of eventemitter warning in tests
1 parent 0e8b827 commit 97f4ecf

38 files changed

+8978
-160
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
coverage/
55
.DS_Store
66
npm-debug.log
7-
dist/
7+
/dist/
88
tsconfig.schema.json
99
tsconfig.schemastore-schema.json
1010
.idea/

ava.config.cjs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module.exports = {
2424
* ts-node, from either node_modules or tests/node_modules
2525
*/
2626

27-
const { existsSync } = require('fs');
27+
const { existsSync, rmSync } = require('fs');
2828
const rimraf = require('rimraf');
2929
const { resolve } = require('path');
3030

@@ -35,6 +35,7 @@ module.exports = {
3535
expect(() => {createRequire(resolve(__dirname, 'tests/foo.js')).resolve('ts-node')}).toThrow();
3636

3737
function remove(p) {
38-
if(existsSync(p)) rimraf.sync(p, {recursive: true})
38+
// Avoid node deprecation warning triggered by rimraf
39+
if(existsSync(p)) (rmSync || rimraf.sync)(p, {recursive: true})
3940
}
4041
}

dist-raw/NODE-LICENSE.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
This directory contains portions of Node.js source code which is licensed as follows:
2+
3+
---
4+
5+
Copyright Joyent, Inc. and other Node contributors.
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a
8+
copy of this software and associated documentation files (the
9+
"Software"), to deal in the Software without restriction, including
10+
without limitation the rights to use, copy, modify, merge, publish,
11+
distribute, sublicense, and/or sell copies of the Software, and to permit
12+
persons to whom the Software is furnished to do so, subject to the
13+
following conditions:
14+
15+
The above copyright notice and this permission notice shall be included
16+
in all copies or substantial portions of the Software.
17+
18+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
21+
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24+
USE OR OTHER DEALINGS IN THE SOFTWARE.

dist-raw/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,26 @@ in a factory function, we will not indent the function body, to avoid whitespace
1111
One obvious problem with this approach: the code has been pulled from one version of node, whereas users of ts-node
1212
run multiple versions of node.
1313
Users running node 12 may see that ts-node behaves like node 14, for example.
14+
15+
## `raw` directory
16+
17+
Within the `raw` directory, we keep unmodified copies of the node source files. This allows us to use diffing tools to
18+
compare files in `raw` to those in `dist-raw`, which will highlight all of the changes we have made. Hopefully, these
19+
changes are as minimal as possible.
20+
21+
## Naming convention
22+
23+
Not used consistently, but the idea is:
24+
25+
`node-<directory>(...-<directory>)-<filename>.js`
26+
27+
`node-internal-errors.js` -> `github.com/nodejs/node/blob/TAG/lib/internal/errors.js`
28+
29+
So, take the path within node's `lib/` directory, and replace slashes with hyphens.
30+
31+
In the `raw` directory, files are suffixed with the version number or revision from which
32+
they were downloaded.
33+
34+
If they have a `stripped` suffix, this means they have large chunks of code deleted, but no other modifications.
35+
This is useful when diffing. Sometimes our `dist-raw` files only have a small part of a much larger node source file.
36+
It is easier to diff `raw/*-stripped.js` against `dist-raw/*.js`.

dist-raw/node-cjs-loader-utils.js

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

dist-raw/node-errors.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// TODO Sync this with node-internal-errors?
2+
13
exports.codes = {
24
ERR_INPUT_TYPE_NOT_ALLOWED: createErrorCtor(joinArgs('ERR_INPUT_TYPE_NOT_ALLOWED')),
35
ERR_INVALID_ARG_VALUE: createErrorCtor(joinArgs('ERR_INVALID_ARG_VALUE')),

dist-raw/node-internal-errors.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
5+
module.exports = {
6+
createErrRequireEsm
7+
};
8+
9+
// Native ERR_REQUIRE_ESM Error is declared here:
10+
// https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/errors.js#L1294-L1313
11+
// Error class factory is implemented here:
12+
// function E: https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/errors.js#L323-L341
13+
// function makeNodeErrorWithCode: https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/errors.js#L251-L278
14+
// The code below should create an error that matches the native error as closely as possible.
15+
// Third-party libraries which attempt to catch the native ERR_REQUIRE_ESM should recognize our imitation error.
16+
function createErrRequireEsm(filename, parentPath, packageJsonPath) {
17+
const code = 'ERR_REQUIRE_ESM'
18+
const err = new Error(getErrRequireEsmMessage(filename, parentPath, packageJsonPath))
19+
// Set `name` to be used in stack trace, generate stack trace with that name baked in, then re-declare the `name` field.
20+
// This trick is copied from node's source.
21+
err.name = `Error [${ code }]`
22+
err.stack
23+
Object.defineProperty(err, 'name', {
24+
value: 'Error',
25+
enumerable: false,
26+
writable: true,
27+
configurable: true
28+
})
29+
err.code = code
30+
return err
31+
}
32+
33+
// Copy-pasted from https://github.com/nodejs/node/blob/b533fb3508009e5f567cc776daba8fbf665386a6/lib/internal/errors.js#L1293-L1311
34+
// so that our error message is identical to the native message.
35+
function getErrRequireEsmMessage(filename, parentPath = null, packageJsonPath = null) {
36+
const ext = path.extname(filename)
37+
let msg = `Must use import to load ES Module: ${filename}`;
38+
if (parentPath && packageJsonPath) {
39+
const path = require('path');
40+
const basename = path.basename(filename) === path.basename(parentPath) ?
41+
filename : path.basename(filename);
42+
msg +=
43+
'\nrequire() of ES modules is not supported.\nrequire() of ' +
44+
`${filename} ${parentPath ? `from ${parentPath} ` : ''}` +
45+
`is an ES module file as it is a ${ext} file whose nearest parent ` +
46+
`package.json contains "type": "module" which defines all ${ext} ` +
47+
'files in that package scope as ES modules.\nInstead ' +
48+
'change the requiring code to use ' +
49+
'import(), or remove "type": "module" from ' +
50+
`${packageJsonPath}.\n`;
51+
return msg;
52+
}
53+
return msg;
54+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copied from several files in node's source code.
2+
// https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/modules/cjs/loader.js
3+
// Each function and variable below must have a comment linking to the source in node's github repo.
4+
5+
const {
6+
JSONParse,
7+
SafeMap,
8+
StringPrototypeEndsWith,
9+
StringPrototypeLastIndexOf,
10+
StringPrototypeIndexOf,
11+
StringPrototypeSlice,
12+
} = require('./node-primordials');
13+
const path = require('path');
14+
const { sep } = path;
15+
const packageJsonReader = require('./node-internal-modules-package_json_reader');
16+
const {normalizeSlashes} = require('../dist/util');
17+
const {createErrRequireEsm} = require('./node-internal-errors');
18+
19+
20+
21+
// Copied from https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/modules/cjs/loader.js#L249
22+
const packageJsonCache = new SafeMap();
23+
24+
// Copied from https://github.com/nodejs/node/blob/v15.3.0/lib/internal/modules/cjs/loader.js#L275-L304
25+
function readPackage(requestPath) {
26+
const jsonPath = path.resolve(requestPath, 'package.json');
27+
28+
const existing = packageJsonCache.get(jsonPath);
29+
if (existing !== undefined) return existing;
30+
31+
const result = packageJsonReader.read(jsonPath);
32+
const json = result.containsKeys === false ? '{}' : result.string;
33+
if (json === undefined) {
34+
packageJsonCache.set(jsonPath, false);
35+
return false;
36+
}
37+
38+
try {
39+
const parsed = JSONParse(json);
40+
const filtered = {
41+
name: parsed.name,
42+
main: parsed.main,
43+
exports: parsed.exports,
44+
imports: parsed.imports,
45+
type: parsed.type
46+
};
47+
packageJsonCache.set(jsonPath, filtered);
48+
return filtered;
49+
} catch (e) {
50+
e.path = jsonPath;
51+
e.message = 'Error parsing ' + jsonPath + ': ' + e.message;
52+
throw e;
53+
}
54+
}
55+
56+
// Copied from https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/modules/cjs/loader.js#L285-L301
57+
function readPackageScope(checkPath) {
58+
const rootSeparatorIndex = StringPrototypeIndexOf(checkPath, sep);
59+
let separatorIndex;
60+
while (
61+
(separatorIndex = StringPrototypeLastIndexOf(checkPath, sep)) > rootSeparatorIndex
62+
) {
63+
checkPath = StringPrototypeSlice(checkPath, 0, separatorIndex);
64+
if (StringPrototypeEndsWith(checkPath, sep + 'node_modules'))
65+
return false;
66+
const pjson = readPackage(checkPath);
67+
if (pjson) return {
68+
path: checkPath,
69+
data: pjson
70+
};
71+
}
72+
return false;
73+
}
74+
75+
/**
76+
* copied from Module._extensions['.js']
77+
* https://github.com/nodejs/node/blob/v15.3.0/lib/internal/modules/cjs/loader.js#L1113-L1120
78+
* @param {import('../src/index').Service} service
79+
* @param {NodeJS.Module} module
80+
* @param {string} filename
81+
*/
82+
function assertScriptCanLoadAsCJSImpl(service, module, filename) {
83+
const pkg = readPackageScope(filename);
84+
85+
// ts-node modification: allow our configuration to override
86+
const tsNodeClassification = service.moduleTypeClassifier.classifyModule(normalizeSlashes(filename));
87+
if(tsNodeClassification.moduleType === 'cjs') return;
88+
89+
// Function require shouldn't be used in ES modules.
90+
if (tsNodeClassification.moduleType === 'esm' || (pkg && pkg.data && pkg.data.type === 'module')) {
91+
const parentPath = module.parent && module.parent.filename;
92+
const packageJsonPath = pkg ? path.resolve(pkg.path, 'package.json') : null;
93+
throw createErrRequireEsm(filename, parentPath, packageJsonPath);
94+
}
95+
}
96+
97+
module.exports = {
98+
assertScriptCanLoadAsCJSImpl
99+
};

dist-raw/node-esm-default-get-format.js renamed to dist-raw/node-internal-modules-esm-get_format.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
// Copied from https://github.com/raw/nodejs/node/v15.3.0/lib/internal/modules/esm/get_format.js
2-
// Then modified to suite our needs.
3-
// Formatting is intentionally bad to keep the diff as small as possible, to make it easier to merge
4-
// upstream changes and understand our modifications.
52

63
'use strict';
74
const {
@@ -19,7 +16,7 @@ const experimentalJsonModules =
1916
const experimentalSpeciferResolution =
2017
getOptionValue('--experimental-specifier-resolution');
2118
const experimentalWasmModules = getOptionValue('--experimental-wasm-modules');
22-
const { getPackageType } = require('./node-esm-resolve-implementation.js').createResolve({tsExtensions: [], jsExtensions: []});
19+
const { getPackageType } = require('./node-internal-modules-esm-resolve').createResolve({tsExtensions: [], jsExtensions: []});
2320
const { URL, fileURLToPath } = require('url');
2421
const { ERR_UNKNOWN_FILE_EXTENSION } = require('./node-errors').codes;
2522

0 commit comments

Comments
 (0)