Skip to content

Commit 808edd8

Browse files
Remove this exports tracking for files with module syntax (#9330)
Co-authored-by: Devon Govett <[email protected]>
1 parent 295958f commit 808edd8

File tree

5 files changed

+67
-25
lines changed

5 files changed

+67
-25
lines changed

packages/core/integration-tests/test/scope-hoisting.js

+41
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
overlayFS,
1818
run,
1919
runBundle,
20+
fsFixture,
2021
} from '@parcel/test-utils';
2122

2223
const bundle = (name, opts = {}) => {
@@ -2487,6 +2488,23 @@ describe('scope hoisting', function () {
24872488
assert.equal(await output, 42);
24882489
});
24892490

2491+
it('should handle TSC polyfills', async () => {
2492+
await fsFixture(overlayFS, __dirname)`
2493+
tsc-polyfill-es6
2494+
library.js:
2495+
var __polyfill = (this && this.__polyfill) || function (a) {return a;};
2496+
export default __polyfill('es6')
2497+
2498+
index.js:
2499+
import value from './library';
2500+
output = value;`;
2501+
2502+
let b = await bundle(path.join(__dirname, 'tsc-polyfill-es6/index.js'), {
2503+
inputFS: overlayFS,
2504+
});
2505+
assert.equal(await run(b), 'es6');
2506+
});
2507+
24902508
describe("considers an asset's closest package.json for sideEffects, not the package through which it found the asset", () => {
24912509
it('handles redirects up the tree', async () => {
24922510
let b = await bundle(
@@ -5265,6 +5283,29 @@ describe('scope hoisting', function () {
52655283

52665284
assert.deepEqual(await run(b), {test: 2});
52675285
});
5286+
5287+
it('should handle TSC polyfills', async () => {
5288+
await fsFixture(overlayFS, __dirname)`
5289+
tsc-polyfill-commonjs
5290+
library.js:
5291+
"use strict";
5292+
var __polyfill = (this && this.__polyfill) || function (a) {return a;};
5293+
exports.value = __polyfill('cjs')
5294+
5295+
index.js:
5296+
const value = require('./library');
5297+
output = value;
5298+
`;
5299+
5300+
let b = await bundle(
5301+
path.join(__dirname, 'tsc-polyfill-commonjs/index.js'),
5302+
{
5303+
inputFS: overlayFS,
5304+
},
5305+
);
5306+
5307+
assert.deepEqual(await run(b), {value: 'cjs'});
5308+
});
52685309
});
52695310

52705311
it('should not throw with JS included from HTML', async function () {

packages/transformers/js/core/src/collect.rs

+7-23
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ pub struct Collect {
7878
in_function: bool,
7979
in_assign: bool,
8080
in_class: bool,
81+
is_module: bool,
8182
}
8283

8384
#[derive(Debug, Serialize)]
@@ -120,12 +121,14 @@ impl Collect {
120121
ignore_mark: Mark,
121122
global_mark: Mark,
122123
trace_bailouts: bool,
124+
is_module: bool,
123125
) -> Self {
124126
Collect {
125127
source_map,
126128
decls,
127129
ignore_mark,
128130
global_mark,
131+
is_module,
129132
static_cjs_exports: true,
130133
has_cjs_exports: false,
131134
is_esm: false,
@@ -690,7 +693,9 @@ impl Visit for Collect {
690693
}
691694
Expr::This(_this) => {
692695
if self.in_module_this {
693-
handle_export!();
696+
if !self.is_module {
697+
handle_export!();
698+
}
694699
} else if !self.in_class {
695700
if let MemberProp::Ident(prop) = &node.prop {
696701
self.this_exprs.insert(id!(prop), (prop.clone(), node.span));
@@ -767,27 +772,6 @@ impl Visit for Collect {
767772
self.used_imports.insert(id!(ident));
768773
}
769774
}
770-
Expr::Bin(bin_expr) => {
771-
if self.in_module_this {
772-
// Some TSC polyfills use a pattern like below.
773-
// We want to avoid marking these modules as CJS
774-
// e.g. var _polyfill = (this && this.polyfill) || function () {}
775-
if matches!(bin_expr.op, BinaryOp::LogicalAnd) && matches!(*bin_expr.left, Expr::This(..))
776-
{
777-
match &*bin_expr.right {
778-
Expr::Member(member_expr) => {
779-
if matches!(*member_expr.obj, Expr::This(..))
780-
&& matches!(member_expr.prop, MemberProp::Ident(..))
781-
{
782-
return;
783-
}
784-
}
785-
_ => {}
786-
}
787-
}
788-
}
789-
node.visit_children_with(self);
790-
}
791775
_ => {
792776
node.visit_children_with(self);
793777
}
@@ -820,7 +804,7 @@ impl Visit for Collect {
820804
}
821805

822806
fn visit_this_expr(&mut self, node: &ThisExpr) {
823-
if self.in_module_this {
807+
if !self.is_module && self.in_module_this {
824808
self.has_cjs_exports = true;
825809
self.static_cjs_exports = false;
826810
self.add_bailout(node.span, BailoutReason::FreeExports);

packages/transformers/js/core/src/fs.rs

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub fn inline_fs<'a>(
1717
global_mark: Mark,
1818
project_root: &'a str,
1919
deps: &'a mut Vec<DependencyDescriptor>,
20+
is_module: bool,
2021
) -> impl Fold + 'a {
2122
InlineFS {
2223
filename: Path::new(filename).to_path_buf(),
@@ -26,6 +27,7 @@ pub fn inline_fs<'a>(
2627
Mark::fresh(Mark::root()),
2728
global_mark,
2829
false,
30+
is_module,
2931
),
3032
global_mark,
3133
project_root,

packages/transformers/js/core/src/hoist.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -1140,11 +1140,21 @@ mod tests {
11401140
);
11411141

11421142
let mut parser = Parser::new_from(lexer);
1143-
match parser.parse_module() {
1144-
Ok(module) => swc_core::common::GLOBALS.set(&Globals::new(), || {
1143+
match parser.parse_program() {
1144+
Ok(program) => swc_core::common::GLOBALS.set(&Globals::new(), || {
11451145
swc_core::ecma::transforms::base::helpers::HELPERS.set(
11461146
&swc_core::ecma::transforms::base::helpers::Helpers::new(false),
11471147
|| {
1148+
let is_module = program.is_module();
1149+
let module = match program {
1150+
Program::Module(module) => module,
1151+
Program::Script(script) => Module {
1152+
span: script.span,
1153+
shebang: None,
1154+
body: script.body.into_iter().map(ModuleItem::Stmt).collect(),
1155+
},
1156+
};
1157+
11481158
let unresolved_mark = Mark::fresh(Mark::root());
11491159
let global_mark = Mark::fresh(Mark::root());
11501160
let module = module.fold_with(&mut resolver(unresolved_mark, global_mark, false));
@@ -1155,6 +1165,7 @@ mod tests {
11551165
Mark::fresh(Mark::root()),
11561166
global_mark,
11571167
true,
1168+
is_module,
11581169
);
11591170
module.visit_with(&mut collect);
11601171

@@ -1444,6 +1455,7 @@ mod tests {
14441455
// We want to avoid marking these modules as CJS
14451456
let (collect, _code, _hoist) = parse(
14461457
r#"
1458+
import 'something';
14471459
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function () {}
14481460
"#,
14491461
);

packages/transformers/js/core/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ pub fn transform(config: Config) -> Result<TransformResult, std::io::Error> {
252252
),
253253
));
254254

255+
let is_module = module.is_module();
255256
// If it's a script, convert into module. This needs to happen after
256257
// the resolver (which behaves differently for non-/strict mode).
257258
let module = match module {
@@ -342,6 +343,7 @@ pub fn transform(config: Config) -> Result<TransformResult, std::io::Error> {
342343
global_mark,
343344
&config.project_root,
344345
&mut fs_deps,
346+
is_module
345347
),
346348
should_inline_fs
347349
),
@@ -448,6 +450,7 @@ pub fn transform(config: Config) -> Result<TransformResult, std::io::Error> {
448450
ignore_mark,
449451
global_mark,
450452
config.trace_bailouts,
453+
is_module,
451454
);
452455
module.visit_with(&mut collect);
453456
if let Some(bailouts) = &collect.bailouts {

0 commit comments

Comments
 (0)