Comparing version 3.24.0 to 3.25.0
const HELPERS = { | ||
require: ` | ||
import {createRequire as CREATE_REQUIRE_NAME} from "module"; | ||
const require = CREATE_REQUIRE_NAME(import.meta.url); | ||
`, | ||
interopRequireWildcard: ` | ||
@@ -128,3 +132,4 @@ function interopRequireWildcard(obj) { | ||
__init() {this.helperNames = {}} | ||
constructor( nameManager) {;this.nameManager = nameManager;HelperManager.prototype.__init.call(this);} | ||
__init2() {this.createRequireName = null} | ||
constructor( nameManager) {;this.nameManager = nameManager;HelperManager.prototype.__init.call(this);HelperManager.prototype.__init2.call(this);} | ||
@@ -159,2 +164,7 @@ getHelperName(baseName) { | ||
); | ||
} else if (baseName === "require") { | ||
if (this.createRequireName === null) { | ||
this.createRequireName = this.nameManager.claimFreeName("_createRequire"); | ||
} | ||
helperCode = helperCode.replace(/CREATE_REQUIRE_NAME/g, this.createRequireName); | ||
} | ||
@@ -161,0 +171,0 @@ if (helperName) { |
@@ -33,3 +33,3 @@ import CJSImportProcessor from "./CJSImportProcessor"; | ||
export function getVersion() { | ||
return "3.24.0"; | ||
return "3.25.0"; | ||
} | ||
@@ -36,0 +36,0 @@ |
@@ -30,2 +30,4 @@ /** | ||
disableESTransforms: t.opt("boolean"), | ||
preserveDynamicImport: t.opt("boolean"), | ||
injectCreateRequireForImportRequire: t.opt("boolean"), | ||
}); | ||
@@ -32,0 +34,0 @@ |
@@ -56,4 +56,20 @@ import {createCheckers} from "ts-interface-checker"; | ||
export function validateOptions(options) { | ||
OptionsChecker.strictCheck(options); | ||
} |
@@ -35,4 +35,5 @@ | ||
isTypeScriptTransformEnabled, | ||
preserveDynamicImport, | ||
) { | ||
super();this.rootTransformer = rootTransformer;this.tokens = tokens;this.importProcessor = importProcessor;this.nameManager = nameManager;this.reactHotLoaderTransformer = reactHotLoaderTransformer;this.enableLegacyBabel5ModuleInterop = enableLegacyBabel5ModuleInterop;this.isTypeScriptTransformEnabled = isTypeScriptTransformEnabled;CJSImportTransformer.prototype.__init.call(this);CJSImportTransformer.prototype.__init2.call(this);CJSImportTransformer.prototype.__init3.call(this);; | ||
super();this.rootTransformer = rootTransformer;this.tokens = tokens;this.importProcessor = importProcessor;this.nameManager = nameManager;this.reactHotLoaderTransformer = reactHotLoaderTransformer;this.enableLegacyBabel5ModuleInterop = enableLegacyBabel5ModuleInterop;this.isTypeScriptTransformEnabled = isTypeScriptTransformEnabled;this.preserveDynamicImport = preserveDynamicImport;CJSImportTransformer.prototype.__init.call(this);CJSImportTransformer.prototype.__init2.call(this);CJSImportTransformer.prototype.__init3.call(this);; | ||
this.declarationInfo = isTypeScriptTransformEnabled | ||
@@ -119,2 +120,7 @@ ? getDeclarationInfo(tokens) | ||
if (this.tokens.matches2(tt._import, tt.parenL)) { | ||
if (this.preserveDynamicImport) { | ||
// Bail out, only making progress for this one token. | ||
this.tokens.copyToken(); | ||
return; | ||
} | ||
this.tokens.replaceToken("Promise.resolve().then(() => require"); | ||
@@ -121,0 +127,0 @@ const contextId = this.tokens.currentToken().contextId; |
import {ContextualKeyword} from "../parser/tokenizer/keywords"; | ||
@@ -24,2 +25,3 @@ import {TokenType as tt} from "../parser/tokenizer/types"; | ||
@@ -29,2 +31,3 @@ constructor( | ||
nameManager, | ||
helperManager, | ||
reactHotLoaderTransformer, | ||
@@ -34,3 +37,3 @@ isTypeScriptTransformEnabled, | ||
) { | ||
super();this.tokens = tokens;this.nameManager = nameManager;this.reactHotLoaderTransformer = reactHotLoaderTransformer;this.isTypeScriptTransformEnabled = isTypeScriptTransformEnabled;; | ||
super();this.tokens = tokens;this.nameManager = nameManager;this.helperManager = helperManager;this.reactHotLoaderTransformer = reactHotLoaderTransformer;this.isTypeScriptTransformEnabled = isTypeScriptTransformEnabled;; | ||
this.nonTypeIdentifiers = isTypeScriptTransformEnabled | ||
@@ -42,2 +45,3 @@ ? getNonTypeIdentifiers(tokens, options) | ||
: EMPTY_DECLARATION_INFO; | ||
this.injectCreateRequireForImportRequire = Boolean(options.injectCreateRequireForImportRequire); | ||
} | ||
@@ -116,4 +120,15 @@ | ||
elideImportEquals(this.tokens); | ||
} else if (this.injectCreateRequireForImportRequire) { | ||
// We're using require in an environment (Node ESM) that doesn't provide | ||
// it as a global, so generate a helper to import it. | ||
// import -> const | ||
this.tokens.replaceToken("const"); | ||
// Foo | ||
this.tokens.copyToken(); | ||
// = | ||
this.tokens.copyToken(); | ||
// require | ||
this.tokens.replaceToken(this.helperManager.getHelperName("require")); | ||
} else { | ||
// Otherwise, switch `import` to `const`. | ||
// Otherwise, just switch `import` to `const`. | ||
this.tokens.replaceToken("const"); | ||
@@ -120,0 +135,0 @@ } |
@@ -87,2 +87,3 @@ | ||
transforms.includes("typescript"), | ||
Boolean(options.preserveDynamicImport), | ||
), | ||
@@ -95,2 +96,3 @@ ); | ||
this.nameManager, | ||
this.helperManager, | ||
reactHotLoaderTransformer, | ||
@@ -97,0 +99,0 @@ transforms.includes("typescript"), |
@@ -86,3 +86,3 @@ | ||
let isESPrivate = false; | ||
let isDeclare = false; | ||
let isDeclareOrAbstract = false; | ||
while (isAccessModifier(tokens.currentToken())) { | ||
@@ -95,4 +95,4 @@ if (tokens.matches1(tt._static)) { | ||
} | ||
if (tokens.matches1(tt._declare)) { | ||
isDeclare = true; | ||
if (tokens.matches1(tt._declare) || tokens.matches1(tt._abstract)) { | ||
isDeclareOrAbstract = true; | ||
} | ||
@@ -156,8 +156,8 @@ tokens.nextToken(); | ||
}); | ||
} else if (!disableESTransforms || isDeclare) { | ||
} else if (!disableESTransforms || isDeclareOrAbstract) { | ||
// This is a regular field declaration, like `x;`. With the class transform enabled, we just | ||
// remove the line so that no output is produced. With the class transform disabled, we | ||
// usually want to preserve the declaration (but still strip types), but if the `declare` | ||
// keyword is specified, we should remove the line to avoid initializing the value to | ||
// undefined. | ||
// or `abstract` keyword is specified, we should remove the line to avoid initializing the | ||
// value to undefined. | ||
rangesToRemove.push({start: statementStartIndex, end: tokens.currentIndex()}); | ||
@@ -164,0 +164,0 @@ } |
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); | ||
const HELPERS = { | ||
require: ` | ||
import {createRequire as CREATE_REQUIRE_NAME} from "module"; | ||
const require = CREATE_REQUIRE_NAME(import.meta.url); | ||
`, | ||
interopRequireWildcard: ` | ||
@@ -128,3 +132,4 @@ function interopRequireWildcard(obj) { | ||
__init() {this.helperNames = {}} | ||
constructor( nameManager) {;this.nameManager = nameManager;HelperManager.prototype.__init.call(this);} | ||
__init2() {this.createRequireName = null} | ||
constructor( nameManager) {;this.nameManager = nameManager;HelperManager.prototype.__init.call(this);HelperManager.prototype.__init2.call(this);} | ||
@@ -159,2 +164,7 @@ getHelperName(baseName) { | ||
); | ||
} else if (baseName === "require") { | ||
if (this.createRequireName === null) { | ||
this.createRequireName = this.nameManager.claimFreeName("_createRequire"); | ||
} | ||
helperCode = helperCode.replace(/CREATE_REQUIRE_NAME/g, this.createRequireName); | ||
} | ||
@@ -161,0 +171,0 @@ if (helperName) { |
@@ -33,3 +33,3 @@ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _CJSImportProcessor = require('./CJSImportProcessor'); var _CJSImportProcessor2 = _interopRequireDefault(_CJSImportProcessor); | ||
function getVersion() { | ||
return "3.24.0"; | ||
return "3.25.0"; | ||
} exports.getVersion = getVersion; | ||
@@ -36,0 +36,0 @@ |
@@ -30,2 +30,4 @@ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }/** | ||
disableESTransforms: t.opt("boolean"), | ||
preserveDynamicImport: t.opt("boolean"), | ||
injectCreateRequireForImportRequire: t.opt("boolean"), | ||
}); exports.Options = Options; | ||
@@ -32,0 +34,0 @@ |
@@ -56,4 +56,20 @@ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _tsinterfacechecker = require('ts-interface-checker'); | ||
function validateOptions(options) { | ||
OptionsChecker.strictCheck(options); | ||
} exports.validateOptions = validateOptions; |
@@ -35,4 +35,5 @@ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
isTypeScriptTransformEnabled, | ||
preserveDynamicImport, | ||
) { | ||
super();this.rootTransformer = rootTransformer;this.tokens = tokens;this.importProcessor = importProcessor;this.nameManager = nameManager;this.reactHotLoaderTransformer = reactHotLoaderTransformer;this.enableLegacyBabel5ModuleInterop = enableLegacyBabel5ModuleInterop;this.isTypeScriptTransformEnabled = isTypeScriptTransformEnabled;CJSImportTransformer.prototype.__init.call(this);CJSImportTransformer.prototype.__init2.call(this);CJSImportTransformer.prototype.__init3.call(this);; | ||
super();this.rootTransformer = rootTransformer;this.tokens = tokens;this.importProcessor = importProcessor;this.nameManager = nameManager;this.reactHotLoaderTransformer = reactHotLoaderTransformer;this.enableLegacyBabel5ModuleInterop = enableLegacyBabel5ModuleInterop;this.isTypeScriptTransformEnabled = isTypeScriptTransformEnabled;this.preserveDynamicImport = preserveDynamicImport;CJSImportTransformer.prototype.__init.call(this);CJSImportTransformer.prototype.__init2.call(this);CJSImportTransformer.prototype.__init3.call(this);; | ||
this.declarationInfo = isTypeScriptTransformEnabled | ||
@@ -119,2 +120,7 @@ ? _getDeclarationInfo2.default.call(void 0, tokens) | ||
if (this.tokens.matches2(_types.TokenType._import, _types.TokenType.parenL)) { | ||
if (this.preserveDynamicImport) { | ||
// Bail out, only making progress for this one token. | ||
this.tokens.copyToken(); | ||
return; | ||
} | ||
this.tokens.replaceToken("Promise.resolve().then(() => require"); | ||
@@ -121,0 +127,0 @@ const contextId = this.tokens.currentToken().contextId; |
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var _keywords = require('../parser/tokenizer/keywords'); | ||
@@ -24,2 +25,3 @@ var _types = require('../parser/tokenizer/types'); | ||
@@ -29,2 +31,3 @@ constructor( | ||
nameManager, | ||
helperManager, | ||
reactHotLoaderTransformer, | ||
@@ -34,3 +37,3 @@ isTypeScriptTransformEnabled, | ||
) { | ||
super();this.tokens = tokens;this.nameManager = nameManager;this.reactHotLoaderTransformer = reactHotLoaderTransformer;this.isTypeScriptTransformEnabled = isTypeScriptTransformEnabled;; | ||
super();this.tokens = tokens;this.nameManager = nameManager;this.helperManager = helperManager;this.reactHotLoaderTransformer = reactHotLoaderTransformer;this.isTypeScriptTransformEnabled = isTypeScriptTransformEnabled;; | ||
this.nonTypeIdentifiers = isTypeScriptTransformEnabled | ||
@@ -42,2 +45,3 @@ ? _getNonTypeIdentifiers.getNonTypeIdentifiers.call(void 0, tokens, options) | ||
: _getDeclarationInfo.EMPTY_DECLARATION_INFO; | ||
this.injectCreateRequireForImportRequire = Boolean(options.injectCreateRequireForImportRequire); | ||
} | ||
@@ -116,4 +120,15 @@ | ||
_elideImportEquals2.default.call(void 0, this.tokens); | ||
} else if (this.injectCreateRequireForImportRequire) { | ||
// We're using require in an environment (Node ESM) that doesn't provide | ||
// it as a global, so generate a helper to import it. | ||
// import -> const | ||
this.tokens.replaceToken("const"); | ||
// Foo | ||
this.tokens.copyToken(); | ||
// = | ||
this.tokens.copyToken(); | ||
// require | ||
this.tokens.replaceToken(this.helperManager.getHelperName("require")); | ||
} else { | ||
// Otherwise, switch `import` to `const`. | ||
// Otherwise, just switch `import` to `const`. | ||
this.tokens.replaceToken("const"); | ||
@@ -120,0 +135,0 @@ } |
@@ -87,2 +87,3 @@ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
transforms.includes("typescript"), | ||
Boolean(options.preserveDynamicImport), | ||
), | ||
@@ -95,2 +96,3 @@ ); | ||
this.nameManager, | ||
this.helperManager, | ||
reactHotLoaderTransformer, | ||
@@ -97,0 +99,0 @@ transforms.includes("typescript"), |
@@ -10,2 +10,3 @@ import type NameManager from "./NameManager"; | ||
}; | ||
createRequireName: string | null; | ||
constructor(nameManager: NameManager); | ||
@@ -12,0 +13,0 @@ getHelperName(baseName: keyof typeof HELPERS): string; |
@@ -46,3 +46,19 @@ export declare type Transform = "jsx" | "typescript" | "flow" | "imports" | "react-hot-loader" | "jest"; | ||
disableESTransforms?: boolean; | ||
/** | ||
* If specified, the imports transform does not attempt to change dynamic import() | ||
* expressions into require() calls. | ||
*/ | ||
preserveDynamicImport?: boolean; | ||
/** | ||
* Only relevant when targeting ESM (i.e. when the imports transform is *not* | ||
* specified). This flag changes the behavior of TS require imports: | ||
* | ||
* import Foo = require("foo"); | ||
* | ||
* to import createRequire, create a require function, and use that function. | ||
* This is the TS behavior with module: nodenext and makes it easier for the | ||
* same code to target ESM and CJS. | ||
*/ | ||
injectCreateRequireForImportRequire?: boolean; | ||
} | ||
export declare function validateOptions(options: Options): void; |
@@ -18,2 +18,3 @@ import type CJSImportProcessor from "../CJSImportProcessor"; | ||
readonly isTypeScriptTransformEnabled: boolean; | ||
readonly preserveDynamicImport: boolean; | ||
private hadExport; | ||
@@ -23,3 +24,3 @@ private hadNamedExport; | ||
private declarationInfo; | ||
constructor(rootTransformer: RootTransformer, tokens: TokenProcessor, importProcessor: CJSImportProcessor, nameManager: NameManager, reactHotLoaderTransformer: ReactHotLoaderTransformer | null, enableLegacyBabel5ModuleInterop: boolean, isTypeScriptTransformEnabled: boolean); | ||
constructor(rootTransformer: RootTransformer, tokens: TokenProcessor, importProcessor: CJSImportProcessor, nameManager: NameManager, reactHotLoaderTransformer: ReactHotLoaderTransformer | null, enableLegacyBabel5ModuleInterop: boolean, isTypeScriptTransformEnabled: boolean, preserveDynamicImport: boolean); | ||
getPrefixCode(): string; | ||
@@ -26,0 +27,0 @@ getSuffixCode(): string; |
@@ -0,1 +1,2 @@ | ||
import type { HelperManager } from "../HelperManager"; | ||
import type { Options } from "../index"; | ||
@@ -13,2 +14,3 @@ import type NameManager from "../NameManager"; | ||
readonly nameManager: NameManager; | ||
readonly helperManager: HelperManager; | ||
readonly reactHotLoaderTransformer: ReactHotLoaderTransformer | null; | ||
@@ -18,3 +20,4 @@ readonly isTypeScriptTransformEnabled: boolean; | ||
private declarationInfo; | ||
constructor(tokens: TokenProcessor, nameManager: NameManager, reactHotLoaderTransformer: ReactHotLoaderTransformer | null, isTypeScriptTransformEnabled: boolean, options: Options); | ||
private injectCreateRequireForImportRequire; | ||
constructor(tokens: TokenProcessor, nameManager: NameManager, helperManager: HelperManager, reactHotLoaderTransformer: ReactHotLoaderTransformer | null, isTypeScriptTransformEnabled: boolean, options: Options); | ||
process(): boolean; | ||
@@ -21,0 +24,0 @@ private processImportEquals; |
@@ -86,3 +86,3 @@ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); | ||
let isESPrivate = false; | ||
let isDeclare = false; | ||
let isDeclareOrAbstract = false; | ||
while (isAccessModifier(tokens.currentToken())) { | ||
@@ -95,4 +95,4 @@ if (tokens.matches1(_types.TokenType._static)) { | ||
} | ||
if (tokens.matches1(_types.TokenType._declare)) { | ||
isDeclare = true; | ||
if (tokens.matches1(_types.TokenType._declare) || tokens.matches1(_types.TokenType._abstract)) { | ||
isDeclareOrAbstract = true; | ||
} | ||
@@ -156,8 +156,8 @@ tokens.nextToken(); | ||
}); | ||
} else if (!disableESTransforms || isDeclare) { | ||
} else if (!disableESTransforms || isDeclareOrAbstract) { | ||
// This is a regular field declaration, like `x;`. With the class transform enabled, we just | ||
// remove the line so that no output is produced. With the class transform disabled, we | ||
// usually want to preserve the declaration (but still strip types), but if the `declare` | ||
// keyword is specified, we should remove the line to avoid initializing the value to | ||
// undefined. | ||
// or `abstract` keyword is specified, we should remove the line to avoid initializing the | ||
// value to undefined. | ||
rangesToRemove.push({start: statementStartIndex, end: tokens.currentIndex()}); | ||
@@ -164,0 +164,0 @@ } |
{ | ||
"name": "sucrase", | ||
"version": "3.24.0", | ||
"version": "3.25.0", | ||
"description": "Super-fast alternative to Babel for when you can target modern JS runtimes", | ||
@@ -66,3 +66,3 @@ "author": "Alan Pierce <alangpierce@gmail.com>", | ||
"prettier": "^2.6.2", | ||
"sucrase": "^3.23.0", | ||
"sucrase": "^3.24.0", | ||
"test262-harness": "^10.0.0", | ||
@@ -69,0 +69,0 @@ "ts-interface-builder": "^0.3.3", |
@@ -37,10 +37,10 @@ # Sucrase | ||
Time Speed | ||
Sucrase 1.64 seconds 220221 lines per second | ||
swc 2.13 seconds 169502 lines per second | ||
esbuild 3.02 seconds 119738 lines per second | ||
TypeScript 24.18 seconds 14937 lines per second | ||
Babel 27.22 seconds 13270 lines per second | ||
Sucrase 0.57 seconds 636975 lines per second | ||
swc 1.19 seconds 304526 lines per second | ||
esbuild 1.45 seconds 248692 lines per second | ||
TypeScript 8.98 seconds 40240 lines per second | ||
Babel 9.18 seconds 39366 lines per second | ||
``` | ||
Details: Measured on January 2021. Tools run in single-threaded mode without warm-up. See the | ||
Details: Measured on July 2022. Tools run in single-threaded mode without warm-up. See the | ||
[benchmark code](https://github.com/alangpierce/sucrase/blob/main/benchmark/benchmark.ts) | ||
@@ -66,3 +66,7 @@ for methodology and caveats. | ||
(`require`/`module.exports`) using the same approach as Babel and TypeScript | ||
with `--esModuleInterop`. Also includes dynamic `import`. | ||
with `--esModuleInterop`. If `preserveDynamicImport` is specified in the Sucrase | ||
options, then dynamic `import` expressions are left alone, which is particularly | ||
useful in Node to load ESM-only libraries. If `preserveDynamicImport` is not | ||
specified, `import` expressions are transformed into a promise-wrapped call to | ||
`require`. | ||
* **react-hot-loader**: Performs the equivalent of the `react-hot-loader/babel` | ||
@@ -76,2 +80,8 @@ transform in the [react-hot-loader](https://github.com/gaearon/react-hot-loader) | ||
When the `imports` transform is *not* specified (i.e. when targeting ESM), the | ||
`injectCreateRequireForImportRequire` option can be specified to transform TS | ||
`import foo = require("foo");` in a way that matches the | ||
[TypeScript 4.7 behavior](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#commonjs-interoperability) | ||
with `module: nodenext`. | ||
These newer JS features are transformed by default: | ||
@@ -78,0 +88,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1040194
26420
266