SWC low level visitors #823
jerrykingxyz
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Summary
Explain how swc transform the source js and explain low-level visitors which in used
NOTE: This page is written base on swc v1.3.1
Glossary
visitor
visitor
is the minimal unit to access and change ast, usually it is a struct which impl Fold, FoldMut, Visit or VisitMutpass
pass
is a special visitor, it can ensure sub visitor run in order.Guide-level explanation
Flow diagram
Swc have three function to transform js -
process_js
,process_js_file
,process_js_with_custom_pass
.Bacause of the
process_js
andprocess_js_file
are just wrappers forprocess_js_with_custom_pass
, we just need to see howprocess_js_with_custom_pass
works.There are four main function calls in
process_js_with_custom_pass
:read_config
Scan
.swcrc
file form every parent dir of current work file, and return the nearest config.config.build_as_input
Transform input config and generate pass.
run config.pass + custom_after_pass
Run all of pass to transform ast
print
Transform ast to string
Visitors (Execute order sort)
Firstly all scopes (fn, block) has it's own SyntaxContext.
Resolver visits all identifiers in module, and look for binding identifies in the scope. Those identifiers now have the SyntaxContext of scope (fn, block). While doing so, resolver tries to resolve normal identifiers (no hygiene info) as a reference to identifier of scope. If the resolver find suitable variable, the identifier reference will have same context as the variable.
Some rule to check ast. can add (feature = "non_critical_lints") to enable more rules.
Transform js decorator
Transform import assertions
typescript::strip_with_jsx (condition: syntax.typescript())
Transform typescript to javascript. If you are using jsx, you should use this before jsx pass
plugins (condition: feature = "plugin" or feature = "plugin-bytecheck")
Cache and run experimental.plugins
custom_before_pass
Run custom_before_pass input by
process_js_with_custom_pass
react::react (condition: syntax.jsx())
Transform jsx to js.
const_modules (condition: jsc.transform.const_modules)
Transform const modules
Set variables to inline.
Allow to export default, more info see @babel/plugin-proposal-export-default-from
Performs simplify-expr, inlining, remove-dead-branch and dce until nothing changes.
Transform json to optimize performance of literals
Remove useless paren
Make private field in class checkable, more info see babel-plugin-proposal-private-property-in-object
Transform source code to compat es version, if
env
exists useswc_ecma_preset_env::preset_env
, else will transform tojsc.target
esversionmodules::import_analysis::import_analyzer (condition: module.type is commonjs, amd, umd)
Analysis source code import, and mark some helper enabled
compat::reserved_words::reserved_words
Transform keyword variables to _keyword, more info see babel-plugin-transform-reserved-words
Inject enabled helpers to source code
ModuleConfig::build
Transform esm to CommonJS or UMD/AMD
MinifierPass
Minify js code
hygiene_with_config
The pass actually modifies the identifiers in the way that different identifier (with respect to span hygiene) becomes different identifier. (e.g.
a1
fora#6
,a2
fora#23
)fixer
Fixes ast nodes before printing so semantics are preserved
jest::jest (condition: jsc.transform.hidden.jest)
Some transform for jest,
hidden
options only use for other swc libdropped_comments_preserver (condition: jsc.preserve_all_comments)
Keep all comments be preserved during compilation
Conclusion
process_js_with_custom_pass
and remove some useless visitor to make the transition process clearer and more controllableparse
&generate
process to make the compilation more reasonablegenerate
visitors:ModuleConfig::build
to the endBeta Was this translation helpful? Give feedback.
All reactions