mirror of
https://github.com/swc-project/swc.git
synced 2024-09-11 16:55:27 +03:00
feat(es): Add an option to disable builtin transforms (#7873)
This commit is contained in:
parent
eed290319e
commit
71d01ec127
@ -324,7 +324,7 @@ impl Options {
|
||||
config: Option<Config>,
|
||||
comments: Option<&'a SingleThreadedComments>,
|
||||
custom_before_pass: impl FnOnce(&Program) -> P,
|
||||
) -> Result<BuiltInput<impl 'a + swc_ecma_visit::Fold>, Error>
|
||||
) -> Result<BuiltInput<Box<dyn 'a + Fold>>, Error>
|
||||
where
|
||||
P: 'a + swc_ecma_visit::Fold,
|
||||
{
|
||||
@ -759,88 +759,95 @@ impl Options {
|
||||
noop()
|
||||
};
|
||||
|
||||
let pass = chain!(
|
||||
lint_to_fold(swc_ecma_lints::rules::all(LintParams {
|
||||
program: &program,
|
||||
lint_config: &lints,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
es_version,
|
||||
source_map: cm.clone(),
|
||||
})),
|
||||
// Decorators may use type information
|
||||
Optional::new(
|
||||
match transform.decorator_version.unwrap_or_default() {
|
||||
DecoratorVersion::V202112 => {
|
||||
Either::Left(decorators(decorators::Config {
|
||||
legacy: transform.legacy_decorator.into_bool(),
|
||||
emit_metadata: transform.decorator_metadata.into_bool(),
|
||||
use_define_for_class_fields: !assumptions.set_public_class_fields,
|
||||
}))
|
||||
}
|
||||
DecoratorVersion::V202203 => {
|
||||
Either::Right(
|
||||
let pass: Box<dyn Fold> = if experimental
|
||||
.disable_builtin_transforms_for_internal_testing
|
||||
.into_bool()
|
||||
{
|
||||
Box::new(plugin_transforms)
|
||||
} else {
|
||||
Box::new(chain!(
|
||||
lint_to_fold(swc_ecma_lints::rules::all(LintParams {
|
||||
program: &program,
|
||||
lint_config: &lints,
|
||||
top_level_ctxt,
|
||||
unresolved_ctxt,
|
||||
es_version,
|
||||
source_map: cm.clone(),
|
||||
})),
|
||||
// Decorators may use type information
|
||||
Optional::new(
|
||||
match transform.decorator_version.unwrap_or_default() {
|
||||
DecoratorVersion::V202112 => {
|
||||
Either::Left(decorators(decorators::Config {
|
||||
legacy: transform.legacy_decorator.into_bool(),
|
||||
emit_metadata: transform.decorator_metadata.into_bool(),
|
||||
use_define_for_class_fields: !assumptions.set_public_class_fields,
|
||||
}))
|
||||
}
|
||||
DecoratorVersion::V202203 => {
|
||||
Either::Right(
|
||||
swc_ecma_transforms::proposals::decorator_2022_03::decorator_2022_03(),
|
||||
)
|
||||
}
|
||||
},
|
||||
syntax.decorators()
|
||||
),
|
||||
// The transform strips import assertions, so it's only enabled if
|
||||
// keep_import_assertions is false.
|
||||
Optional::new(import_assertions(), !keep_import_assertions),
|
||||
Optional::new(
|
||||
typescript::strip_with_jsx::<Option<&dyn Comments>>(
|
||||
cm.clone(),
|
||||
typescript::Config {
|
||||
pragma: Some(
|
||||
transform
|
||||
.react
|
||||
.pragma
|
||||
.clone()
|
||||
.unwrap_or_else(default_pragma)
|
||||
),
|
||||
pragma_frag: Some(
|
||||
transform
|
||||
.react
|
||||
.pragma_frag
|
||||
.clone()
|
||||
.unwrap_or_else(default_pragma_frag)
|
||||
),
|
||||
ts_enum_config: TsEnumConfig {
|
||||
treat_const_enum_as_enum: transform
|
||||
.treat_const_enum_as_enum
|
||||
.into_bool(),
|
||||
ts_enum_is_readonly: assumptions.ts_enum_is_readonly,
|
||||
},
|
||||
import_export_assign_config,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
comments.map(|v| v as _),
|
||||
top_level_mark
|
||||
syntax.decorators()
|
||||
),
|
||||
syntax.typescript()
|
||||
),
|
||||
plugin_transforms,
|
||||
custom_before_pass(&program),
|
||||
// handle jsx
|
||||
Optional::new(
|
||||
react::react::<&dyn Comments>(
|
||||
cm.clone(),
|
||||
comments.map(|v| v as _),
|
||||
transform.react,
|
||||
top_level_mark,
|
||||
unresolved_mark
|
||||
// The transform strips import assertions, so it's only enabled if
|
||||
// keep_import_assertions is false.
|
||||
Optional::new(import_assertions(), !keep_import_assertions),
|
||||
Optional::new(
|
||||
typescript::strip_with_jsx::<Option<&dyn Comments>>(
|
||||
cm.clone(),
|
||||
typescript::Config {
|
||||
pragma: Some(
|
||||
transform
|
||||
.react
|
||||
.pragma
|
||||
.clone()
|
||||
.unwrap_or_else(default_pragma)
|
||||
),
|
||||
pragma_frag: Some(
|
||||
transform
|
||||
.react
|
||||
.pragma_frag
|
||||
.clone()
|
||||
.unwrap_or_else(default_pragma_frag)
|
||||
),
|
||||
ts_enum_config: TsEnumConfig {
|
||||
treat_const_enum_as_enum: transform
|
||||
.treat_const_enum_as_enum
|
||||
.into_bool(),
|
||||
ts_enum_is_readonly: assumptions.ts_enum_is_readonly,
|
||||
},
|
||||
import_export_assign_config,
|
||||
..Default::default()
|
||||
},
|
||||
comments.map(|v| v as _),
|
||||
top_level_mark
|
||||
),
|
||||
syntax.typescript()
|
||||
),
|
||||
syntax.jsx()
|
||||
),
|
||||
pass,
|
||||
Optional::new(jest::jest(), transform.hidden.jest.into_bool()),
|
||||
Optional::new(
|
||||
dropped_comments_preserver(comments.cloned()),
|
||||
preserve_all_comments
|
||||
),
|
||||
);
|
||||
plugin_transforms,
|
||||
custom_before_pass(&program),
|
||||
// handle jsx
|
||||
Optional::new(
|
||||
react::react::<&dyn Comments>(
|
||||
cm.clone(),
|
||||
comments.map(|v| v as _),
|
||||
transform.react,
|
||||
top_level_mark,
|
||||
unresolved_mark
|
||||
),
|
||||
syntax.jsx()
|
||||
),
|
||||
pass,
|
||||
Optional::new(jest::jest(), transform.hidden.jest.into_bool()),
|
||||
Optional::new(
|
||||
dropped_comments_preserver(comments.cloned()),
|
||||
preserve_all_comments
|
||||
),
|
||||
))
|
||||
};
|
||||
|
||||
Ok(BuiltInput {
|
||||
program,
|
||||
@ -1454,6 +1461,9 @@ pub struct JscExperimental {
|
||||
/// and will not be considered as breaking changes.
|
||||
#[serde(default)]
|
||||
pub cache_root: Option<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub disable_builtin_transforms_for_internal_testing: BoolConfig<false>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
|
@ -733,7 +733,7 @@ impl Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn read_config(&self, opts: &Options, name: &FileName) -> Result<Option<Config>, Error> {
|
||||
static CUR_DIR: Lazy<PathBuf> = Lazy::new(|| {
|
||||
if cfg!(target_arch = "wasm32") {
|
||||
@ -845,7 +845,7 @@ impl Compiler {
|
||||
/// This method handles merging of config.
|
||||
///
|
||||
/// This method does **not** parse module.
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn parse_js_as_input<'a, P>(
|
||||
&'a self,
|
||||
fm: Lrc<SourceFile>,
|
||||
@ -908,7 +908,7 @@ impl Compiler {
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn transform(
|
||||
&self,
|
||||
handler: &Handler,
|
||||
@ -936,7 +936,7 @@ impl Compiler {
|
||||
///
|
||||
/// This means, you can use `noop_visit_type`, `noop_fold_type` and
|
||||
/// `noop_visit_mut_type` in your visitor to reduce the binary size.
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn process_js_with_custom_pass<P1, P2>(
|
||||
&self,
|
||||
fm: Arc<SourceFile>,
|
||||
@ -997,11 +997,11 @@ impl Compiler {
|
||||
None
|
||||
};
|
||||
|
||||
self.process_js_inner(handler, orig.as_ref(), config)
|
||||
self.apply_transforms(handler, orig.as_ref(), config)
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip(self, handler, opts))]
|
||||
#[tracing::instrument(skip(self, handler, opts))]
|
||||
pub fn process_js_file(
|
||||
&self,
|
||||
fm: Arc<SourceFile>,
|
||||
@ -1019,7 +1019,7 @@ impl Compiler {
|
||||
)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn minify(
|
||||
&self,
|
||||
fm: Arc<SourceFile>,
|
||||
@ -1186,7 +1186,7 @@ impl Compiler {
|
||||
/// You can use custom pass with this method.
|
||||
///
|
||||
/// There exists a [PassBuilder] to help building custom passes.
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn process_js(
|
||||
&self,
|
||||
handler: &Handler,
|
||||
@ -1207,8 +1207,8 @@ impl Compiler {
|
||||
)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
fn process_js_inner(
|
||||
#[tracing::instrument(name = "swc::Compiler::apply_transforms", skip_all)]
|
||||
fn apply_transforms(
|
||||
&self,
|
||||
handler: &Handler,
|
||||
orig: Option<&sourcemap::SourceMap>,
|
||||
@ -1281,7 +1281,7 @@ fn find_swcrc(path: &Path, root: &Path, root_mode: RootMode) -> Option<PathBuf>
|
||||
None
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
#[tracing::instrument(skip_all)]
|
||||
fn load_swcrc(path: &Path) -> Result<Rc, Error> {
|
||||
let content = read_to_string(path).context("failed to read config (.swcrc) file")?;
|
||||
|
||||
|
31
node-swc/__tests__/transform/experimental.mjs
Normal file
31
node-swc/__tests__/transform/experimental.mjs
Normal file
@ -0,0 +1,31 @@
|
||||
import swc from "../../..";
|
||||
|
||||
describe("when jsc.experimentalDisableBuiltinTransforms is true", () => {
|
||||
it("should preserve TypeScript", async () => {
|
||||
const { code } = await swc.transform(
|
||||
`
|
||||
const hello: Type = () => {
|
||||
console.log('hello');
|
||||
};
|
||||
`,
|
||||
{
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: "typescript",
|
||||
},
|
||||
experimental: {
|
||||
disableBuiltinTransformsForInternalTesting: true,
|
||||
},
|
||||
},
|
||||
minify: false,
|
||||
}
|
||||
);
|
||||
|
||||
expect(code).toMatchInlineSnapshot(`
|
||||
"const hello: Type = ()=>{
|
||||
console.log(\\"hello\\");
|
||||
};
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
@ -178,6 +178,6 @@
|
||||
],
|
||||
"packageManager": "yarn@3.5.0",
|
||||
"dependencies": {
|
||||
"@swc/types": "^0.1.3"
|
||||
"@swc/types": "^0.1.4"
|
||||
}
|
||||
}
|
||||
|
@ -591,6 +591,9 @@ export interface JscConfig {
|
||||
*/
|
||||
keepClassNames?: boolean;
|
||||
|
||||
/**
|
||||
* This is experimental, and can be removed without a major version bump.
|
||||
*/
|
||||
experimental?: {
|
||||
optimizeHygiene?: boolean;
|
||||
keepImportAssertions?: boolean;
|
||||
@ -608,6 +611,11 @@ export interface JscConfig {
|
||||
* Second parameter of tuple is JSON based configuration for the plugin.
|
||||
*/
|
||||
plugins?: Array<[string, Record<string, any>]>;
|
||||
|
||||
/**
|
||||
* Disable builtin transforms. If enabled, only Wasm plugins are used.
|
||||
*/
|
||||
disableBuiltinTransformsForInternalTesting?: boolean;
|
||||
};
|
||||
|
||||
baseUrl?: string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@swc/types",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"description": "Typings for the swc project.",
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
|
10
yarn.lock
10
yarn.lock
@ -2564,7 +2564,7 @@ __metadata:
|
||||
"@swc/core-win32-x64-msvc": 1.2.146
|
||||
"@swc/helpers": ^0.5.0
|
||||
"@swc/plugin-jest": latest
|
||||
"@swc/types": ^0.1.3
|
||||
"@swc/types": ^0.1.4
|
||||
"@taplo/cli": ^0.3.2
|
||||
"@types/jest": ^28.1.4
|
||||
"@types/node": ^20.5.0
|
||||
@ -2647,10 +2647,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/types@npm:^0.1.3":
|
||||
version: 0.1.3
|
||||
resolution: "@swc/types@npm:0.1.3"
|
||||
checksum: 89b86ac338076a4c7ad3b8b016bb7d9ea6357517716d46232c372dc21f93166e08ed334da0a157e02cd5a1b1ff651542ddcd6f43988ee74b16f837a840681143
|
||||
"@swc/types@npm:^0.1.4":
|
||||
version: 0.1.4
|
||||
resolution: "@swc/types@npm:0.1.4"
|
||||
checksum: 9b09de7dca8e4b19bfb43f9e332c771855158cb761d26000807fe858447ecbc5342a6c257b26d9aa5497f7138fc58913693e2bee222e5042e0e8f57c2979ae66
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user