Update swc (#33063)

This commit is contained in:
Donny/강동윤 2022-01-10 19:37:32 +09:00 committed by GitHub
parent 320986a2b8
commit 87dbd03eb0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 386 additions and 576 deletions

File diff suppressed because it is too large Load diff

View file

@ -14,21 +14,21 @@ fxhash = "0.2.1"
pathdiff = "0.2.0" pathdiff = "0.2.0"
serde = "1" serde = "1"
serde_json = "1" serde_json = "1"
styled_components = "0.6.0" styled_components = "0.9.0"
swc = "0.98.0" swc = "0.110.0"
swc_atoms = "0.2.7" swc_atoms = "0.2.7"
swc_common = { version = "0.15.0", features = ["concurrent", "sourcemap"] } swc_common = { version = "0.16.0", features = ["concurrent", "sourcemap"] }
swc_css = "0.44.0" swc_css = "0.45.0"
swc_ecma_loader = { version = "0.25.0", features = ["node", "lru"] } swc_ecma_loader = { version = "0.26.0", features = ["node", "lru"] }
swc_ecmascript = { version = "0.98.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } swc_ecmascript = { version = "0.105.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] }
swc_node_base = "0.5.1" swc_node_base = "0.5.1"
swc_stylis = "0.41.1" swc_stylis = "0.42.0"
tracing = {version = "0.1.28", features = ["release_max_level_off"]} tracing = {version = "0.1.28", features = ["release_max_level_off"]}
regex = "1.5" regex = "1.5"
[dev-dependencies] [dev-dependencies]
swc_ecma_transforms_testing = "0.51.0" swc_ecma_transforms_testing = "0.56.0"
testing = "0.16.0" testing = "0.17.0"
walkdir = "2.3.2" walkdir = "2.3.2"

View file

@ -11,7 +11,7 @@ use swc_ecmascript::{
visit::{noop_fold_type, Fold}, visit::{noop_fold_type, Fold},
}; };
/// Note: This paths requires runnning `resolver` **before** running this. /// Note: This paths requires running `resolver` **before** running this.
pub fn next_ssg() -> impl Fold { pub fn next_ssg() -> impl Fold {
Repeat::new(NextSsg { Repeat::new(NextSsg {
state: Default::default(), state: Default::default(),
@ -19,7 +19,7 @@ pub fn next_ssg() -> impl Fold {
}) })
} }
/// State of the transforms. Shared by the anayzer and the tranform. /// State of the transforms. Shared by the analyzer and the transform.
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct State { struct State {
/// Identifiers referenced by non-data function codes. /// Identifiers referenced by non-data function codes.
@ -45,11 +45,7 @@ struct State {
impl State { impl State {
fn is_data_identifier(&mut self, i: &Ident) -> Result<bool, Error> { fn is_data_identifier(&mut self, i: &Ident) -> Result<bool, Error> {
let ssg_exports = &[ let ssg_exports = &["getStaticProps", "getStaticPaths", "getServerSideProps"];
"getStaticProps",
"getStaticPaths",
"getServerSideProps",
];
if ssg_exports.contains(&&*i.sym) { if ssg_exports.contains(&&*i.sym) {
if &*i.sym == "getServerSideProps" { if &*i.sym == "getServerSideProps" {
@ -125,7 +121,9 @@ impl Fold for Analyzer<'_> {
} }
fn fold_export_named_specifier(&mut self, s: ExportNamedSpecifier) -> ExportNamedSpecifier { fn fold_export_named_specifier(&mut self, s: ExportNamedSpecifier) -> ExportNamedSpecifier {
self.add_ref(s.orig.to_id()); if let ModuleExportName::Ident(id) = &s.orig {
self.add_ref(id.to_id());
}
s s
} }
@ -189,7 +187,7 @@ impl Fold for Analyzer<'_> {
e e
} }
/// Drops [ExportDecl] if all speicifers are removed. /// Drops [ExportDecl] if all specifiers are removed.
fn fold_module_item(&mut self, s: ModuleItem) -> ModuleItem { fn fold_module_item(&mut self, s: ModuleItem) -> ModuleItem {
match s { match s {
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(e)) if !e.specifiers.is_empty() => { ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(e)) if !e.specifiers.is_empty() => {
@ -211,8 +209,7 @@ impl Fold for Analyzer<'_> {
ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(e)) => match &e.decl { ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(e)) => match &e.decl {
Decl::Fn(f) => { Decl::Fn(f) => {
// Drop getStaticProps. // Drop getStaticProps.
if let Ok(is_data_identifier) = self.state.is_data_identifier(&f.ident) if let Ok(is_data_identifier) = self.state.is_data_identifier(&f.ident) {
{
if is_data_identifier { if is_data_identifier {
return ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP })); return ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP }));
} }
@ -493,29 +490,38 @@ impl Fold for NextSsg {
n.specifiers.retain(|s| { n.specifiers.retain(|s| {
let preserve = match s { let preserve = match s {
ExportSpecifier::Namespace(ExportNamespaceSpecifier { name: exported, .. }) ExportSpecifier::Namespace(ExportNamespaceSpecifier {
name: ModuleExportName::Ident(exported),
..
})
| ExportSpecifier::Default(ExportDefaultSpecifier { exported, .. }) | ExportSpecifier::Default(ExportDefaultSpecifier { exported, .. })
| ExportSpecifier::Named(ExportNamedSpecifier { | ExportSpecifier::Named(ExportNamedSpecifier {
exported: Some(exported), exported: Some(ModuleExportName::Ident(exported)),
.. ..
}) => self }) => self
.state .state
.is_data_identifier(&exported) .is_data_identifier(&exported)
.map(|is_data_identifier| !is_data_identifier), .map(|is_data_identifier| !is_data_identifier),
ExportSpecifier::Named(s) => self ExportSpecifier::Named(ExportNamedSpecifier {
orig: ModuleExportName::Ident(orig),
..
}) => self
.state .state
.is_data_identifier(&s.orig) .is_data_identifier(&orig)
.map(|is_data_identifier| !is_data_identifier), .map(|is_data_identifier| !is_data_identifier),
_ => Ok(true),
}; };
match preserve { match preserve {
Ok(false) => { Ok(false) => {
tracing::trace!( tracing::trace!("Dropping a export specifier because it's a data identifier");
"Dropping a export specifier because it's a data identifier"
);
match s { match s {
ExportSpecifier::Named(ExportNamedSpecifier { orig, .. }) => { ExportSpecifier::Named(ExportNamedSpecifier {
orig: ModuleExportName::Ident(orig),
..
}) => {
self.state.should_run_again = true; self.state.should_run_again = true;
self.state.refs_from_data_fn.insert(orig.to_id()); self.state.refs_from_data_fn.insert(orig.to_id());
} }

View file

@ -5,153 +5,176 @@ use swc_ecmascript::utils::HANDLER;
use swc_ecmascript::visit::{Fold, FoldWith}; use swc_ecmascript::visit::{Fold, FoldWith};
pub fn page_config(is_development: bool, is_page_file: bool) -> impl Fold { pub fn page_config(is_development: bool, is_page_file: bool) -> impl Fold {
PageConfig { PageConfig {
is_development, is_development,
is_page_file, is_page_file,
..Default::default() ..Default::default()
} }
} }
pub fn page_config_test() -> impl Fold { pub fn page_config_test() -> impl Fold {
PageConfig { PageConfig {
in_test: true, in_test: true,
is_page_file: true, is_page_file: true,
..Default::default() ..Default::default()
} }
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct PageConfig { struct PageConfig {
drop_bundle: bool, drop_bundle: bool,
in_test: bool, in_test: bool,
is_development: bool, is_development: bool,
is_page_file: bool, is_page_file: bool,
} }
const STRING_LITERAL_DROP_BUNDLE: &str = "__NEXT_DROP_CLIENT_FILE__"; const STRING_LITERAL_DROP_BUNDLE: &str = "__NEXT_DROP_CLIENT_FILE__";
const CONFIG_KEY: &str = "config"; const CONFIG_KEY: &str = "config";
impl Fold for PageConfig { impl Fold for PageConfig {
fn fold_module_items(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> { fn fold_module_items(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
let mut new_items = vec![]; let mut new_items = vec![];
for item in items { for item in items {
new_items.push(item.fold_with(self)); new_items.push(item.fold_with(self));
if !self.is_development && self.drop_bundle { if !self.is_development && self.drop_bundle {
let timestamp = match self.in_test { let timestamp = match self.in_test {
true => String::from("mock_timestamp"), true => String::from("mock_timestamp"),
false => Utc::now().timestamp().to_string(), false => Utc::now().timestamp().to_string(),
}; };
return vec![ModuleItem::Stmt(Stmt::Decl(Decl::Var(VarDecl { return vec![ModuleItem::Stmt(Stmt::Decl(Decl::Var(VarDecl {
decls: vec![VarDeclarator { decls: vec![VarDeclarator {
name: Pat::Ident(BindingIdent { name: Pat::Ident(BindingIdent {
id: Ident { id: Ident {
sym: STRING_LITERAL_DROP_BUNDLE.into(), sym: STRING_LITERAL_DROP_BUNDLE.into(),
span: DUMMY_SP, span: DUMMY_SP,
optional: false, optional: false,
}, },
type_ann: None, type_ann: None,
}), }),
init: Some(Box::new(Expr::Lit(Lit::Str(Str { init: Some(Box::new(Expr::Lit(Lit::Str(Str {
value: format!("{} {}", STRING_LITERAL_DROP_BUNDLE, timestamp).into(), value: format!("{} {}", STRING_LITERAL_DROP_BUNDLE, timestamp).into(),
span: DUMMY_SP, span: DUMMY_SP,
kind: StrKind::Synthesized {}, kind: StrKind::Synthesized {},
has_escape: false, has_escape: false,
})))), })))),
span: DUMMY_SP, span: DUMMY_SP,
definite: false, definite: false,
}], }],
span: DUMMY_SP, span: DUMMY_SP,
kind: VarDeclKind::Const, kind: VarDeclKind::Const,
declare: false, declare: false,
})))]; })))];
} }
}
new_items
} }
new_items fn fold_export_decl(&mut self, export: ExportDecl) -> ExportDecl {
} match &export.decl {
Decl::Var(var_decl) => {
fn fold_export_decl(&mut self, export: ExportDecl) -> ExportDecl { for decl in &var_decl.decls {
match &export.decl { let mut is_config = false;
Decl::Var(var_decl) => { if let Pat::Ident(ident) = &decl.name {
for decl in &var_decl.decls { if &ident.id.sym == CONFIG_KEY {
let mut is_config = false; is_config = true;
if let Pat::Ident(ident) = &decl.name {
if &ident.id.sym == CONFIG_KEY {
is_config = true;
}
}
if is_config {
if let Some(expr) = &decl.init {
if let Expr::Object(obj) = &**expr {
for prop in &obj.props {
if let PropOrSpread::Prop(prop) = prop {
if let Prop::KeyValue(kv) = &**prop {
match &kv.key {
PropName::Ident(ident) => {
if &ident.sym == "amp" {
if let Expr::Lit(Lit::Bool(Bool { value, .. })) = &*kv.value {
if *value && self.is_page_file {
self.drop_bundle = true;
}
} else if let Expr::Lit(Lit::Str(_)) = &*kv.value {
// Do not replace bundle
} else {
self.handle_error("Invalid value found.", export.span);
}
}
} }
_ => {
self.handle_error("Invalid property found.", export.span);
}
}
} else {
self.handle_error("Invalid property or value.", export.span);
} }
} else {
self.handle_error("Property spread is not allowed.", export.span);
}
}
} else {
self.handle_error("Expected config to be an object.", export.span);
}
} else {
self.handle_error("Expected config to be an object.", export.span);
}
}
}
}
_ => {}
}
export
}
fn fold_export_named_specifier( if is_config {
&mut self, if let Some(expr) = &decl.init {
specifier: ExportNamedSpecifier, if let Expr::Object(obj) = &**expr {
) -> ExportNamedSpecifier { for prop in &obj.props {
match &specifier.exported { if let PropOrSpread::Prop(prop) = prop {
Some(ident) => { if let Prop::KeyValue(kv) = &**prop {
if &ident.sym == CONFIG_KEY { match &kv.key {
self.handle_error("Config cannot be re-exported.", specifier.span) PropName::Ident(ident) => {
if &ident.sym == "amp" {
if let Expr::Lit(Lit::Bool(Bool {
value,
..
})) = &*kv.value
{
if *value && self.is_page_file {
self.drop_bundle = true;
}
} else if let Expr::Lit(Lit::Str(_)) =
&*kv.value
{
// Do not replace
// bundle
} else {
self.handle_error(
"Invalid value found.",
export.span,
);
}
}
}
_ => {
self.handle_error(
"Invalid property found.",
export.span,
);
}
}
} else {
self.handle_error(
"Invalid property or value.",
export.span,
);
}
} else {
self.handle_error(
"Property spread is not allowed.",
export.span,
);
}
}
} else {
self.handle_error("Expected config to be an object.", export.span);
}
} else {
self.handle_error("Expected config to be an object.", export.span);
}
}
}
}
_ => {}
} }
} export
None => { }
if &specifier.orig.sym == CONFIG_KEY {
self.handle_error("Config cannot be re-exported.", specifier.span) fn fold_export_named_specifier(
} &mut self,
} specifier: ExportNamedSpecifier,
) -> ExportNamedSpecifier {
match &specifier.exported {
Some(ident) => {
if let ModuleExportName::Ident(ident) = ident {
if &ident.sym == CONFIG_KEY {
self.handle_error("Config cannot be re-exported.", specifier.span)
}
}
}
None => {
if let ModuleExportName::Ident(ident) = &specifier.orig {
if &ident.sym == CONFIG_KEY {
self.handle_error("Config cannot be re-exported.", specifier.span)
}
}
}
}
specifier
} }
specifier
}
} }
impl PageConfig { impl PageConfig {
fn handle_error(&mut self, details: &str, span: Span) { fn handle_error(&mut self, details: &str, span: Span) {
if self.is_page_file { if self.is_page_file {
let message = format!("Invalid page config export found. {} \ let message = format!("Invalid page config export found. {} \
See: https://nextjs.org/docs/messages/invalid-page-config", details); See: https://nextjs.org/docs/messages/invalid-page-config", details);
HANDLER.with(|handler| handler.struct_span_err(span, &message).emit()); HANDLER.with(|handler| handler.struct_span_err(span, &message).emit());
}
} }
}
} }

View file

@ -84,11 +84,15 @@ impl Fold for ExportShaker {
.filter_map(|spec| { .filter_map(|spec| {
if let ExportSpecifier::Named(named_spec) = spec { if let ExportSpecifier::Named(named_spec) = spec {
if let Some(ident) = &named_spec.exported { if let Some(ident) = &named_spec.exported {
if let ModuleExportName::Ident(ident) = ident {
if self.ignore.contains(&ident.sym) {
return Some(ExportSpecifier::Named(named_spec));
}
}
} else if let ModuleExportName::Ident(ident) = &named_spec.orig {
if self.ignore.contains(&ident.sym) { if self.ignore.contains(&ident.sym) {
return Some(ExportSpecifier::Named(named_spec)); return Some(ExportSpecifier::Named(named_spec));
} }
} else if self.ignore.contains(&named_spec.orig.sym) {
return Some(ExportSpecifier::Named(named_spec));
} }
} }
None None

View file

@ -1,8 +1,7 @@
"use strict"; "use strict";
var _esm = _interopRequireDefault(require("esm")); var a = function(a) {
function _interopRequireDefault(a) {
return a && a.__esModule ? a : { return a && a.__esModule ? a : {
default: a default: a
}; };
} }(require("esm"));
console.log(_esm.default.foo), module.exports = _esm.default; console.log(a.default.foo), module.exports = a.default;

View file

@ -1,52 +1,47 @@
import a from "other"; import a from "other";
function _arrayLikeToArray(a, b) { function b(a, b) {
(null == b || b > a.length) && (b = a.length); (null == b || b > a.length) && (b = a.length);
for(var b = 0, d = new Array(b); b < b; b++)d[b] = a[b]; for(var c = 0, d = new Array(b); c < b; c++)d[c] = a[c];
return d; return d;
} }
function _arrayWithHoles(a) { (function(a, c) {
if (Array.isArray(a)) return a; return (function(a) {
} if (Array.isArray(a)) return a;
function _classCallCheck(a, b) { })(a) || (function(a, c) {
if (!(a instanceof b)) throw new TypeError("Cannot call a class as a function"); var d, e, f = null == a ? null : "undefined" != typeof Symbol && a[Symbol.iterator] || a["@@iterator"];
} if (null != f) {
function _iterableToArrayLimit(a, b) { var g = [], h = !0, i = !1;
var c, d, e = null == a ? null : "undefined" != typeof Symbol && a[Symbol.iterator] || a["@@iterator"];
if (null != e) {
var f = [], g = !0, h = !1;
try {
for(e = e.call(a); !(g = (c = e.next()).done) && (f.push(c.value), !b || f.length !== b); g = !0);
} catch (i) {
h = !0, d = i;
} finally{
try { try {
g || null == e.return || e.return(); for(f = f.call(a); !(h = (d = f.next()).done) && (g.push(d.value), !c || g.length !== c); h = !0);
} catch (j) {
i = !0, e = j;
} finally{ } finally{
if (h) throw d; try {
h || null == f.return || f.return();
} finally{
if (i) throw e;
}
} }
return g;
} }
return f; })(a, c) || (function(a, c) {
} if (a) {
} if ("string" == typeof a) return b(a, c);
function _nonIterableRest() { var d = Object.prototype.toString.call(a).slice(8, -1);
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); if ("Object" === d && a.constructor && (d = a.constructor.name), "Map" === d || "Set" === d) return Array.from(d);
} if ("Arguments" === d || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(d)) return b(a, c);
function _slicedToArray(a, b) { }
return _arrayWithHoles(a) || _iterableToArrayLimit(a, b) || _unsupportedIterableToArray(a, b) || _nonIterableRest(); })(a, c) || (function() {
} throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
function _unsupportedIterableToArray(a, b) { })();
if (a) { })(a, 1)[0];
if ("string" == typeof a) return _arrayLikeToArray(a, b); var c = function() {
var c = Object.prototype.toString.call(a).slice(8, -1);
if ("Object" === c && a.constructor && (c = a.constructor.name), "Map" === c || "Set" === c) return Array.from(c);
if ("Arguments" === c || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c)) return _arrayLikeToArray(a, b);
}
}
var _other = _slicedToArray(a, 1), foo = _other[0], Foo = function() {
"use strict"; "use strict";
_classCallCheck(this, Foo); !function(a, b) {
if (!(a instanceof b)) throw new TypeError("Cannot call a class as a function");
}(this, c);
}; };
export var __N_SSG = !0; export var __N_SSG = !0;
export default function a() { export default function d() {
return React.createElement("div", null); return React.createElement("div", null);
}; };

View file

@ -16,12 +16,12 @@ once_cell = "1.8.0"
serde = "1" serde = "1"
serde_json = "1" serde_json = "1"
next-swc = { version = "0.0.0", path = "../core" } next-swc = { version = "0.0.0", path = "../core" }
swc = "0.98.0" swc = "0.110.0"
swc_atoms = "0.2.7" swc_atoms = "0.2.7"
swc_bundler = { version = "0.91.0", features = ["concurrent"] } swc_bundler = { version = "0.98.0", features = ["concurrent"] }
swc_common = { version = "0.15.0", features = ["concurrent", "sourcemap"] } swc_common = { version = "0.16.0", features = ["concurrent", "sourcemap"] }
swc_ecma_loader = { version = "0.25.0", features = ["node", "lru"] } swc_ecma_loader = { version = "0.26.0", features = ["node", "lru"] }
swc_ecmascript = { version = "0.98.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } swc_ecmascript = { version = "0.105.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] }
swc_node_base = "0.5.1" swc_node_base = "0.5.1"
[build-dependencies] [build-dependencies]

View file

@ -76,6 +76,7 @@ impl Task for BundleTask {
disable_inliner: false, disable_inliner: false,
external_modules: builtins, external_modules: builtins,
module: swc_bundler::ModuleType::Es, module: swc_bundler::ModuleType::Es,
..Default::default()
}, },
Box::new(CustomHook), Box::new(CustomHook),
); );

View file

@ -16,9 +16,9 @@ path-clean = "0.1"
serde = {version = "1", features = ["derive"]} serde = {version = "1", features = ["derive"]}
serde_json = "1" serde_json = "1"
next-swc = { version = "0.0.0", path = "../core" } next-swc = { version = "0.0.0", path = "../core" }
swc = "0.98.0" swc = "0.110.0"
swc_common = { version = "0.15.0", features = ["concurrent", "sourcemap"] } swc_common = { version = "0.16.0", features = ["concurrent", "sourcemap"] }
swc_ecmascript = { version = "0.98.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } swc_ecmascript = { version = "0.105.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] }
tracing = {version = "0.1.28", features = ["release_max_level_off"]} tracing = {version = "0.1.28", features = ["release_max_level_off"]}
wasm-bindgen = {version = "0.2", features = ["serde-serialize"]} wasm-bindgen = {version = "0.2", features = ["serde-serialize"]}
wasm-bindgen-futures = "0.4.8" wasm-bindgen-futures = "0.4.8"