Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/v2' into atlassian
Browse files Browse the repository at this point in the history
* upstream/v2:
  Normalize object literal shorthand even when wrapped (#8155)
  add invalidateOnEnvChange to resolver (#8103)
  Apply unresolved mark to inserted `undefined` identifiers (#8151)
  • Loading branch information
lettertwo committed Jun 3, 2022
2 parents f9ead19 + 3b3b135 commit 62f7f8b
Show file tree
Hide file tree
Showing 31 changed files with 206 additions and 73 deletions.
16 changes: 16 additions & 0 deletions packages/core/core/src/requests/PathRequest.js
Expand Up @@ -67,6 +67,12 @@ async function run({input, api, options}: RunOpts) {
});
let result: ResolverResult = await resolverRunner.resolve(input.dependency);

if (result.invalidateOnEnvChange) {
for (let env of result.invalidateOnEnvChange) {
api.invalidateOnEnvChange(env);
}
}

if (result.invalidateOnFileCreate) {
for (let file of result.invalidateOnFileCreate) {
api.invalidateOnFileCreate(
Expand Down Expand Up @@ -105,6 +111,7 @@ type ResolverResult = {|
assetGroup: ?AssetGroup,
invalidateOnFileCreate?: Array<FileCreateInvalidation>,
invalidateOnFileChange?: Array<FilePath>,
invalidateOnEnvChange?: Array<string>,
diagnostics?: Array<Diagnostic>,
|};

Expand Down Expand Up @@ -185,6 +192,7 @@ export class ResolverRunner {
let diagnostics: Array<Diagnostic> = [];
let invalidateOnFileCreate = [];
let invalidateOnFileChange = [];
let invalidateOnEnvChange = [];
for (let resolver of resolvers) {
try {
let result = await resolver.plugin.resolve({
Expand All @@ -208,6 +216,10 @@ export class ResolverRunner {
dependency.priority = Priority[result.priority];
}

if (result.invalidateOnEnvChange) {
invalidateOnEnvChange.push(...result.invalidateOnEnvChange);
}

if (result.invalidateOnFileCreate) {
invalidateOnFileCreate.push(...result.invalidateOnFileCreate);
}
Expand All @@ -221,6 +233,7 @@ export class ResolverRunner {
assetGroup: null,
invalidateOnFileCreate,
invalidateOnFileChange,
invalidateOnEnvChange,
};
}

Expand Down Expand Up @@ -251,6 +264,7 @@ export class ResolverRunner {
},
invalidateOnFileCreate,
invalidateOnFileChange,
invalidateOnEnvChange,
};
}

Expand Down Expand Up @@ -286,6 +300,7 @@ export class ResolverRunner {
assetGroup: null,
invalidateOnFileCreate,
invalidateOnFileChange,
invalidateOnEnvChange,
};
}

Expand All @@ -308,6 +323,7 @@ export class ResolverRunner {
assetGroup: null,
invalidateOnFileCreate,
invalidateOnFileChange,
invalidateOnEnvChange,
diagnostics,
};
}
Expand Down
@@ -0,0 +1,7 @@
module.exports = function () {
if(process.env.ABC === 'a') {
return require("./unused.js");
} else {
return "ok";
}
};
@@ -0,0 +1 @@
module.exports = "unused";
@@ -0,0 +1,4 @@
{
"extends": "@parcel/config-default",
"resolvers": ["parcel-resolver-can-invalidateonenvchange"]
}
@@ -0,0 +1 @@
const willBeReplaced = true;

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -0,0 +1,4 @@
{
"name": "test-resolver-invalidateonenevchange",
"private": true
}
@@ -0,0 +1,3 @@
const v = require("./b.js");

output = v;
@@ -0,0 +1,7 @@
const value = require("./c.js");

const obj = {
value,
};

exports = module.exports = obj.value;
@@ -0,0 +1 @@
module.exports = 1234;
22 changes: 22 additions & 0 deletions packages/core/integration-tests/test/javascript.js
Expand Up @@ -347,6 +347,28 @@ describe('javascript', function () {
assert(!contents.includes('import'));
});

it('should ignore unused requires after process.env inlining', async function () {
let b = await bundle(
path.join(__dirname, '/integration/env-unused-require/index.js'),
{
env: {ABC: 'XYZ'},
},
);

assertBundles(b, [
{
type: 'js',
assets: ['index.js'],
},
]);

let contents = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8');
assert(!contents.includes('unused'));

let output = await run(b);
assert.strictEqual(output(), 'ok');
});

it('should produce a basic JS bundle with object rest spread support', async function () {
let b = await bundle(
path.join(
Expand Down
20 changes: 20 additions & 0 deletions packages/core/integration-tests/test/plugin.js
Expand Up @@ -190,4 +190,24 @@ parcel-transformer-b`,

assert.equal(await run(b), 2);
});

it('should allow resolvers to invalidateOnEnvChange', async () => {
async function assertAsset(replacedCode) {
let b = await bundle(
path.join(
__dirname,
'/integration/resolver-can-invalidateonenvchange/index.js',
),
{
shouldDisableCache: false,
inputFS: overlayFS,
env: {replacedCode},
},
);
let code = await b.getBundles()[0].getEntryAssets()[0].getCode();
assert(code.indexOf(replacedCode) !== -1);
}
await assertAsset('const replaced = 1;');
await assertAsset('const replaced = 2;');
});
});
14 changes: 12 additions & 2 deletions packages/core/integration-tests/test/scope-hoisting.js
Expand Up @@ -3709,8 +3709,6 @@ describe('scope hoisting', function () {
),
);

// console.log(await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'));

let output = await run(b);
assert.equal(output, 1);
});
Expand Down Expand Up @@ -3775,6 +3773,18 @@ describe('scope hoisting', function () {
assert.deepEqual(output, {foo: 2});
});

it('should support referencing a require in object literal shorthands when wrapped', async function () {
let b = await bundle(
path.join(
__dirname,
'/integration/scope-hoisting/commonjs/wrap-module-obj-literal-require/a.js',
),
);

let output = await run(b);
assert.strictEqual(output, 1234);
});

it('should support typeof require when wrapped', async function () {
// https://github.com/parcel-bundler/parcel/issues/5883
let b = await bundle(
Expand Down
2 changes: 2 additions & 0 deletions packages/core/types/index.js
Expand Up @@ -1502,6 +1502,8 @@ export type ResolveResult = {|
+invalidateOnFileCreate?: Array<FileCreateInvalidation>,
/** A list of files that should invalidate the resolution if modified or deleted. */
+invalidateOnFileChange?: Array<FilePath>,
/** Invalidates the resolution when the given environment variable changes.*/
+invalidateOnEnvChange?: Array<string>,
|};

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/optimizers/image/package.json
Expand Up @@ -37,7 +37,7 @@
"@parcel/utils": "2.0.30",
"@parcel/workers": "2.0.30",
"detect-libc": "^1.0.3",
"self-published": "npm:@parcel/optimizer-image@2.6.1-nightly.2733"
"self-published": "npm:@parcel/optimizer-image@2.6.1-nightly.2736"
},
"devDependencies": {
"@napi-rs/cli": "^2.6.2",
Expand Down
8 changes: 3 additions & 5 deletions packages/transformers/js/core/src/decl_collector.rs
@@ -1,14 +1,12 @@
use std::collections::HashSet;

use swc_atoms::JsWord;
use swc_common::SyntaxContext;
use swc_ecmascript::ast;
use swc_ecmascript::ast::{self, Id};
use swc_ecmascript::visit::{Visit, VisitWith};

/// This pass collects all declarations in a module into a single HashSet of tuples
/// containing identifier names and their associated syntax context (scope).
/// This is used later to determine whether an identifier references a declared variable.
pub fn collect_decls(module: &ast::Module) -> HashSet<(JsWord, SyntaxContext)> {
pub fn collect_decls(module: &ast::Module) -> HashSet<Id> {
let mut c = DeclCollector {
decls: HashSet::new(),
in_var: false,
Expand All @@ -18,7 +16,7 @@ pub fn collect_decls(module: &ast::Module) -> HashSet<(JsWord, SyntaxContext)> {
}

struct DeclCollector {
decls: HashSet<(JsWord, SyntaxContext)>,
decls: HashSet<Id>,
in_var: bool,
}

Expand Down
17 changes: 11 additions & 6 deletions packages/transformers/js/core/src/dependency_collector.rs
Expand Up @@ -5,8 +5,8 @@ use std::path::Path;

use serde::{Deserialize, Serialize};
use swc_atoms::JsWord;
use swc_common::{Mark, SourceMap, Span, SyntaxContext, DUMMY_SP};
use swc_ecmascript::ast::{self, Callee, MemberProp};
use swc_common::{Mark, SourceMap, Span, DUMMY_SP};
use swc_ecmascript::ast::{self, Callee, Id, MemberProp};
use swc_ecmascript::visit::{Fold, FoldWith};

use crate::fold_member_expr_skip_prop;
Expand Down Expand Up @@ -59,8 +59,9 @@ pub struct DependencyDescriptor {
pub fn dependency_collector<'a>(
source_map: &'a SourceMap,
items: &'a mut Vec<DependencyDescriptor>,
decls: &'a HashSet<(JsWord, SyntaxContext)>,
decls: &'a HashSet<Id>,
ignore_mark: swc_common::Mark,
unresolved_mark: swc_common::Mark,
config: &'a Config,
diagnostics: &'a mut Vec<Diagnostic>,
) -> impl Fold + 'a {
Expand All @@ -72,6 +73,7 @@ pub fn dependency_collector<'a>(
require_node: None,
decls,
ignore_mark,
unresolved_mark,
config,
diagnostics,
import_meta: None,
Expand All @@ -84,8 +86,9 @@ struct DependencyCollector<'a> {
in_try: bool,
in_promise: bool,
require_node: Option<ast::CallExpr>,
decls: &'a HashSet<(JsWord, SyntaxContext)>,
decls: &'a HashSet<Id>,
ignore_mark: swc_common::Mark,
unresolved_mark: swc_common::Mark,
config: &'a Config,
diagnostics: &'a mut Vec<Diagnostic>,
import_meta: Option<ast::VarDecl>,
Expand Down Expand Up @@ -828,7 +831,7 @@ impl<'a> Fold for DependencyCollector<'a> {
};

if is_require {
return ast::Expr::Ident(ast::Ident::new("undefined".into(), DUMMY_SP));
return ast::Expr::Ident(get_undefined_ident(self.unresolved_mark));
}

node.fold_children_with(self)
Expand Down Expand Up @@ -1096,7 +1099,7 @@ impl<'a> DependencyCollector<'a> {
fn match_new_url(
&mut self,
expr: &ast::Expr,
decls: &HashSet<(JsWord, SyntaxContext)>,
decls: &HashSet<Id>,
) -> Option<(JsWord, swc_common::Span)> {
use ast::*;

Expand Down Expand Up @@ -1139,6 +1142,7 @@ impl<'a> DependencyCollector<'a> {
None
}

#[allow(clippy::wrong_self_convention)]
fn is_import_meta_url(&mut self, expr: &ast::Expr) -> bool {
use ast::*;

Expand Down Expand Up @@ -1175,6 +1179,7 @@ impl<'a> DependencyCollector<'a> {
}
}

#[allow(clippy::wrong_self_convention)]
fn is_import_meta(&mut self, expr: &ast::Expr) -> bool {
use ast::*;

Expand Down
9 changes: 5 additions & 4 deletions packages/transformers/js/core/src/env_replacer.rs
Expand Up @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
use std::vec;

use swc_atoms::JsWord;
use swc_common::{SyntaxContext, DUMMY_SP};
use swc_common::{Mark, DUMMY_SP};
use swc_ecmascript::ast;
use swc_ecmascript::visit::{Fold, FoldWith};

Expand All @@ -13,10 +13,11 @@ pub struct EnvReplacer<'a> {
pub replace_env: bool,
pub is_browser: bool,
pub env: &'a HashMap<swc_atoms::JsWord, swc_atoms::JsWord>,
pub decls: &'a HashSet<(JsWord, SyntaxContext)>,
pub decls: &'a HashSet<Id>,
pub used_env: &'a mut HashSet<JsWord>,
pub source_map: &'a swc_common::SourceMap,
pub diagnostics: &'a mut Vec<Diagnostic>,
pub unresolved_mark: Mark,
}

impl<'a> Fold for EnvReplacer<'a> {
Expand Down Expand Up @@ -105,7 +106,7 @@ impl<'a> Fold for EnvReplacer<'a> {
right: Box::new(if let Some(init) = &decl.init {
*init.clone()
} else {
Expr::Ident(Ident::new(js_word!("undefined"), DUMMY_SP))
Expr::Ident(get_undefined_ident(self.unresolved_mark))
}),
}))
})
Expand Down Expand Up @@ -214,7 +215,7 @@ impl<'a> EnvReplacer<'a> {
| "valueOf" => {}
_ => {
self.used_env.insert(sym.clone());
return Some(Expr::Ident(Ident::new(js_word!("undefined"), DUMMY_SP)));
return Some(Expr::Ident(get_undefined_ident(self.unresolved_mark)));
}
};
}
Expand Down

0 comments on commit 62f7f8b

Please sign in to comment.