Skip to content

Commit

Permalink
feat(parser): add new javascript parser options
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Oct 8, 2024
1 parent a2771f6 commit cd931cf
Show file tree
Hide file tree
Showing 30 changed files with 683 additions and 3 deletions.
4 changes: 4 additions & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,10 @@ export interface RawJavascriptParserOptions {
worker?: Array<string>
overrideStrict?: string
importMeta?: boolean
requireAsExpression?: boolean
requireDynamic?: boolean
requireResolve?: boolean
importDynamic?: boolean
}

export interface RawLazyCompilationOption {
Expand Down
8 changes: 8 additions & 0 deletions crates/rspack_binding_options/src/options/raw_module/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ pub struct RawJavascriptParserOptions {
pub worker: Option<Vec<String>>,
pub override_strict: Option<String>,
pub import_meta: Option<bool>,
pub require_as_expression: Option<bool>,
pub require_dynamic: Option<bool>,
pub require_resolve: Option<bool>,
pub import_dynamic: Option<bool>,
}

impl From<RawJavascriptParserOptions> for JavascriptParserOptions {
Expand Down Expand Up @@ -307,6 +311,10 @@ impl From<RawJavascriptParserOptions> for JavascriptParserOptions {
.override_strict
.map(|e| OverrideStrict::from(e.as_str())),
import_meta: value.import_meta,
require_as_expression: value.require_as_expression,
require_dynamic: value.require_dynamic,
require_resolve: value.require_resolve,
import_dynamic: value.import_dynamic,
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions crates/rspack_core/src/options/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ pub struct JavascriptParserOptions {
pub worker: Option<Vec<String>>,
pub override_strict: Option<OverrideStrict>,
pub import_meta: Option<bool>,
pub require_as_expression: Option<bool>,
pub require_dynamic: Option<bool>,
pub require_resolve: Option<bool>,
pub import_dynamic: Option<bool>,
}

#[derive(Debug, Clone, MergeFrom)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ pub struct CommonJsImportsParserPlugin;

impl CommonJsImportsParserPlugin {
fn process_resolve(&self, parser: &mut JavascriptParser, call_expr: &CallExpr, weak: bool) {
if matches!(parser.javascript_options.require_resolve, Some(false)) {
return;
}

if call_expr.args.len() != 1 {
return;
}
Expand Down Expand Up @@ -268,6 +272,10 @@ impl CommonJsImportsParserPlugin {
}
}

if matches!(parser.javascript_options.require_dynamic, Some(false)) && !param.is_string() {
return Some(true);
}

// FIXME: should support `LocalModuleDependency`
if self
.process_require_item(parser, call_expr.span, &param)
Expand All @@ -290,6 +298,10 @@ impl CommonJsImportsParserPlugin {
parser: &mut JavascriptParser,
ident: &Ident,
) -> Option<bool> {
if matches!(parser.javascript_options.require_as_expression, Some(false)) {
return Some(true);
}

let start = ident.span().real_lo();
let end = ident.span().real_hi();
let mut dep = CommonJsRequireContextDependency::new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ impl JavascriptParserPlugin for ImportParserPlugin {
parser.blocks.push(Box::new(block));
Some(true)
} else {
if matches!(parser.javascript_options.import_dynamic, Some(false)) {
return Some(true);
}

let ContextModuleScanResult {
context,
reg,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,11 @@ Object {
"dynamicImportPrefetch": false,
"dynamicImportPreload": false,
"exprContextCritical": true,
"importDynamic": true,
"importMeta": true,
"requireAsExpression": true,
"requireDynamic": true,
"requireResolve": true,
"strictExportPresence": false,
"url": true,
"worker": Array [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const dir = process.env.name

import('./other.js')

import('./' + dir + '/other.js')
import(dir)


Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'other';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// TODO: move to webpack-test after merged into webpack

/** @type {import("../../../../types").Configuration} */
module.exports = {
entry: {
bundle0: "./index.js",
test: "./test.js"
},
module: {
parser: {
javascript: {
importDynamic: false
}
}
},
output: {
filename: "[name].js"
},
node: {
__dirname: false
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
findBundle: function (i, options) {
return ["test.js"];
}
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const fs = require("fs");
const path = require("path");

it("import() a dynamical expression should preserve as-is when `importDynamic` is disabled", () => {
const code = fs.readFileSync(path.join(__dirname, "./bundle0.js"), 'utf-8');
expect(code).not.toContain("import('./other.js')");
expect(code).toContain("import('./' + dir + '/other.js')");
expect(code).toContain("import(dir)");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require('./other.js')

const resolve1 = require.resolve
resolve1('./other.js')

const lazyFn = (module, requireFn) => {}
lazyFn('./other.js', require)


Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'other';
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/** @type {import("../../../../types").Configuration} */
module.exports = {
entry: {
bundle0: "./index.js",
test: "./test.js"
},
module: {
parser: {
javascript: {
requireAsExpression: false
}
}
},
output: {
filename: "[name].js"
},
node: {
__dirname: false
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// TODO: move to webpack-test after merged into webpack

module.exports = {
findBundle: function (i, options) {
return ["test.js"];
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const fs = require("fs");
const path = require("path");

it("use require as a expression should preserve as-is when `requireAsExpression` is disabled", () => {
const code = fs.readFileSync(path.join(__dirname, "./bundle0.js"), 'utf-8');
expect(code).not.toContain("require('./other.js')");
expect(code).toContain("resolve1('./other.js')");
expect(code).toContain(`lazyFn('./other.js', require)`);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const dir = process.env.name

const require1 = require(dir)

const require2 = require('./other.js')

const require3 = require('./foo/' + dir + '.js')

const require4 = require(a + './foo/' + dir + '.js')

const require5 = require(dir ? './foo/' + dir + '.js' : './foo/nested' + dir + 'js')
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'other';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// TODO: move to webpack-test after merged into webpack

/** @type {import("../../../../types").Configuration} */
module.exports = {
entry: {
bundle0: "./index.js",
test: "./test.js"
},
module: {
parser: {
javascript: {
requireDynamic: false
}
}
},
output: {
filename: "[name].js"
},
node: {
__dirname: false
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
findBundle: function (i, options) {
return ["test.js"];
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const fs = require("fs");
const path = require("path");

it("require a dynamical expression should preserve as-is when `requireDynamic` is disabled", () => {
const code = fs.readFileSync(path.join(__dirname, "./bundle0.js"), 'utf-8');
expect(code).toContain("require(dir)");
expect(code).not.toContain("require('./other.js')");
expect(code).toContain("require('./foo/' + dir + '.js')");
expect(code).toContain("require(a + './foo/' + dir + '.js')");
expect(code).toContain("require(dir ? './foo/' + dir + '.js' : './foo/nested' + dir + 'js')");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const dir = process.env.DIR_READ_FROM_RUNTIME

const resolve1 = require.resolve(dir)

const resolve2 = require.resolve('./other.js')

const resolve3 = require.resolve('./foo/' + dir + '.js')

const resolve4 = require.resolve(process.env.RANDOM ? './foo/' + dir + '.js' : './bar/' + dir + 'js')


// Can't handle, `require` will turn into expression
// const resolve5 = require.resolve
// resolve5('./other.js')

// Can't handle, `require` will turn into `undefined`
// const __require = require
// const resolve6 = __require.resolve('./other.js')

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// TODO: move to webpack-test after merged into webpack

/** @type {import("../../../../types").Configuration} */
module.exports = {
entry: {
bundle0: "./index.js",
test: "./test.js"
},
module: {
parser: {
javascript: {
requireResolve: false
}
}
},
output: {
filename: "[name].js"
},
node: {
__dirname: false
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
findBundle: function (i, options) {
return ["test.js"];
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const fs = require("fs");
const path = require("path");

it("`require.resolve` should preserve as-is when `requireResolve` is disabled", () => {
const code = fs.readFileSync(path.join(__dirname, "./bundle0.js"), 'utf-8');
expect(code).toContain("require.resolve(dir)");
expect(code).toContain("require.resolve('./other.js')");
expect(code).toContain("require.resolve('./foo/' + dir + '.js')");
expect(code).toContain("require.resolve(process.env.RANDOM ? './foo/' + dir + '.js' : './bar/' + dir + 'js')");
});
Loading

0 comments on commit cd931cf

Please sign in to comment.