Skip to content

Commit 847e9cb

Browse files
committed
feat(rstest_plugin): handle import.meta.dirname and import.meta.filename
1 parent 1c2d7ab commit 847e9cb

File tree

7 files changed

+169
-19
lines changed

7 files changed

+169
-19
lines changed

crates/rspack_plugin_javascript/src/visitors/dependency/parser/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ pub struct JavascriptParser<'parser> {
231231
pub(crate) worker_index: u32,
232232
pub(crate) build_meta: &'parser mut BuildMeta,
233233
pub build_info: &'parser mut BuildInfo,
234-
pub(crate) resource_data: &'parser ResourceData,
234+
pub resource_data: &'parser ResourceData,
235235
pub(crate) plugin_drive: Rc<JavaScriptParserPluginDrive>,
236236
pub(crate) definitions_db: ScopeInfoDB,
237237
pub(crate) compiler_options: &'parser CompilerOptions,

crates/rspack_plugin_rstest/src/parser_plugin.rs

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,46 @@
1-
use rspack_plugin_javascript::JavascriptParserPlugin;
1+
use rspack_core::{ConstDependency, SpanExt};
2+
use rspack_plugin_javascript::{
3+
utils, utils::eval, visitors::JavascriptParser, JavascriptParserPlugin,
4+
};
5+
use swc_core::common::Spanned;
26

37
use crate::module_path_name_dependency::{ModulePathNameDependency, NameType};
48

59
const DIR_NAME: &str = "__dirname";
610
const FILE_NAME: &str = "__filename";
11+
const IMPORT_META_DIRNAME: &str = "import.meta.dirname";
12+
const IMPORT_META_FILENAME: &str = "import.meta.filename";
13+
14+
#[derive(PartialEq)]
15+
enum ModulePathType {
16+
DirName,
17+
FileName,
18+
}
719

820
#[derive(Debug, Default)]
921
pub struct RstestParserPlugin;
1022

23+
impl RstestParserPlugin {
24+
fn import_meta(&self, parser: &mut JavascriptParser, r#type: ModulePathType) -> String {
25+
if r#type == ModulePathType::FileName {
26+
if let Some(resource_path) = &parser.resource_data.resource_path {
27+
format!("'{}'", resource_path.clone().into_string())
28+
} else {
29+
"''".to_string()
30+
}
31+
} else {
32+
let resource_path = parser
33+
.resource_data
34+
.resource_path
35+
.as_deref()
36+
.and_then(|p| p.parent())
37+
.map(|p| p.to_string())
38+
.unwrap_or_default();
39+
format!("'{}'", resource_path)
40+
}
41+
}
42+
}
43+
1144
impl JavascriptParserPlugin for RstestParserPlugin {
1245
fn identifier(
1346
&self,
@@ -36,4 +69,92 @@ impl JavascriptParserPlugin for RstestParserPlugin {
3669
_ => None,
3770
}
3871
}
72+
73+
fn evaluate_typeof<'a>(
74+
&self,
75+
_parser: &mut JavascriptParser,
76+
expr: &'a swc_core::ecma::ast::UnaryExpr,
77+
for_name: &str,
78+
) -> Option<utils::eval::BasicEvaluatedExpression<'a>> {
79+
let mut evaluated = None;
80+
if for_name == IMPORT_META_DIRNAME || for_name == IMPORT_META_FILENAME {
81+
evaluated = Some("string".to_string());
82+
}
83+
evaluated.map(|e| eval::evaluate_to_string(e, expr.span.real_lo(), expr.span.real_hi()))
84+
}
85+
86+
fn evaluate_identifier(
87+
&self,
88+
parser: &mut JavascriptParser,
89+
ident: &str,
90+
start: u32,
91+
end: u32,
92+
) -> Option<eval::BasicEvaluatedExpression<'static>> {
93+
if ident == IMPORT_META_DIRNAME {
94+
Some(eval::evaluate_to_string(
95+
self.import_meta(parser, ModulePathType::DirName),
96+
start,
97+
end,
98+
))
99+
} else if ident == IMPORT_META_FILENAME {
100+
Some(eval::evaluate_to_string(
101+
self.import_meta(parser, ModulePathType::FileName),
102+
start,
103+
end,
104+
))
105+
} else {
106+
None
107+
}
108+
}
109+
110+
fn r#typeof(
111+
&self,
112+
parser: &mut JavascriptParser,
113+
unary_expr: &swc_core::ecma::ast::UnaryExpr,
114+
for_name: &str,
115+
) -> Option<bool> {
116+
if for_name == IMPORT_META_DIRNAME || for_name == IMPORT_META_FILENAME {
117+
parser
118+
.presentational_dependencies
119+
.push(Box::new(ConstDependency::new(
120+
unary_expr.span().into(),
121+
"'string'".into(),
122+
None,
123+
)));
124+
Some(true)
125+
} else {
126+
None
127+
}
128+
}
129+
130+
fn member(
131+
&self,
132+
parser: &mut JavascriptParser,
133+
member_expr: &swc_core::ecma::ast::MemberExpr,
134+
for_name: &str,
135+
) -> Option<bool> {
136+
if for_name == IMPORT_META_DIRNAME {
137+
let result = self.import_meta(parser, ModulePathType::DirName);
138+
parser
139+
.presentational_dependencies
140+
.push(Box::new(ConstDependency::new(
141+
member_expr.span().into(),
142+
result.into(),
143+
None,
144+
)));
145+
Some(true)
146+
} else if for_name == IMPORT_META_FILENAME {
147+
let result = self.import_meta(parser, ModulePathType::FileName);
148+
parser
149+
.presentational_dependencies
150+
.push(Box::new(ConstDependency::new(
151+
member_expr.span().into(),
152+
result.into(),
153+
None,
154+
)));
155+
Some(true)
156+
} else {
157+
None
158+
}
159+
}
39160
}

packages/rspack-test-tools/tests/configCases/plugins/rstest/index.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,28 @@ const path = require('path');
44
it("Insert module path names with concatenateModules", () => {
55
const sourceDir = path.resolve(__dirname, "../../../../");
66
const content = fs.readFileSync(path.resolve(__dirname, "modulePathName.js"), "utf-8");
7+
// __dirname and __filename renamed after concatenation
78
expect(content).toContain(`const foo_filename = '${path.resolve(sourceDir, "./configCases/plugins/rstest/src/foo.js")}'`);
8-
expect(content).toMatch(`const bar_dirname = '${path.resolve(sourceDir, "./configCases/plugins/rstest/src")}'`);
9+
expect(content).toMatch(`const foo_dirname = '${path.resolve(sourceDir, "./configCases/plugins/rstest/src")}'`);
10+
11+
expect(content).toMatch(`const metaFile1 = '${path.resolve(sourceDir, "./configCases/plugins/rstest/src/foo.js")}'`)
12+
expect(content).toMatch(`const metaDir1 = '${path.resolve(sourceDir, "./configCases/plugins/rstest/src")}'`)
13+
14+
expect(content).toContain(`const typeofMetaDir = 'string'`);
15+
expect(content).toContain(`const typeofMetaFile = 'string'`);
916
});
1017

1118
it("Insert module path names without concatenateModules", () => {
1219
const sourceDir = path.resolve(__dirname, "../../../../");
1320
const content = fs.readFileSync(path.resolve(__dirname, "modulePathNameWithoutConcatenate.js"), "utf-8");
1421
expect(content).toContain(`const __filename = '${path.resolve(sourceDir, "./configCases/plugins/rstest/src/foo.js")}'`);
1522
expect(content).toMatch(`const __dirname = '${path.resolve(sourceDir, "./configCases/plugins/rstest/src")}'`);
16-
1723
expect(content.match(/const __dirname = /g).length).toBe(2);
1824
expect(content.match(/const __filename = /g).length).toBe(2);
25+
26+
expect(content).toMatch(`const metaFile1 = '${path.resolve(sourceDir, "./configCases/plugins/rstest/src/foo.js")}'`)
27+
expect(content).toMatch(`const metaDir1 = '${path.resolve(sourceDir, "./configCases/plugins/rstest/src")}'`)
28+
29+
expect(content).toContain(`const typeofMetaDir = 'string'`);
30+
expect(content).toContain(`const typeofMetaFile = 'string'`);
1931
});
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export const barValue = 'bar: ' + __dirname
1+
export const file = __filename
2+
export const dir = __dirname

packages/rspack-test-tools/tests/configCases/plugins/rstest/src/baz.js

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1-
export const fooValue1 = 'foo: ' + __filename
2-
export const fooValue2 = 'foo: ' + __filename
3-
export const fooValue3 = 'foo: ' + __filename
1+
export const file1 = __filename
2+
export const file2 = __filename
3+
export const metaFile1 = import.meta.filename
4+
export const typeofMetaFile = typeof import.meta.filename
5+
6+
export const dir1 = __dirname
7+
export const dir2 = __dirname
8+
export const metaDir1 = import.meta.dirname
9+
export const typeofMetaDir = typeof import.meta.dirname
10+
11+
if (import.meta.filename.indexOf("foo.js") === -1) {
12+
require("fail")
13+
};
14+
15+
if (import.meta.dirname.indexOf("plugins/rstest/src") === -1) {
16+
require("fail")
17+
};
18+
Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import { fooValue1, fooValue2, fooValue3 } from './foo'
2-
import { barValue } from './bar'
3-
import { bazValue1, bazValue2 } from './baz'
1+
import { file1, file2, metaFile1, dir1, dir2, metaDir1, typeofMetaFile, typeofMetaDir } from './foo'
2+
import { file, dir } from './bar'
43

54
console.log(
6-
fooValue1,
7-
fooValue2,
8-
fooValue3,
9-
barValue,
10-
bazValue1,
11-
bazValue2
5+
file1,
6+
file2,
7+
metaFile1,
8+
dir1,
9+
dir2,
10+
metaDir1,
11+
typeofMetaFile,
12+
typeofMetaDir,
13+
file,
14+
dir
1215
)

0 commit comments

Comments
 (0)