Skip to content

Commit 8c206cf

Browse files
authored
feat: plugin for parse (#266)
1 parent 788dad9 commit 8c206cf

16 files changed

+521
-480
lines changed

.npmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
registry=https://registry.npmjs.org/

crates/mako/src/build.rs

+3
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ impl Compiler {
244244
"\n\nResolve Error: Resolve \"{}\" failed from \"{}\" \n",
245245
source, target
246246
);
247+
// TODO: remove me
248+
// 当 entry resolve 文件失败时,get_targets 自身会失败
249+
println!("err: {}", err);
247250

248251
let id = ModuleId::new(target.clone());
249252
let module_graph = context.module_graph.read().unwrap();

crates/mako/src/compiler.rs

+14
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,20 @@ mod tests {
265265
index_js_content.contains(".foo {\n color: red;\n}"),
266266
"css loader"
267267
);
268+
assert!(index_js_content.contains(".jpg\");\n}"), "big.jpg in css");
269+
assert!(
270+
index_js_content.contains(".big {\n background: url(\""),
271+
"small.png in css"
272+
);
273+
assert!(
274+
index_js_content.contains("big.jpg\": function("),
275+
"include big.jpg in js"
276+
);
277+
assert!(
278+
index_js_content.contains("small.png\": function("),
279+
"include small.png in js"
280+
);
281+
// TODO: svg
268282
}
269283

270284
fn compile(base: &str) -> (Vec<String>, HashMap<String, String>) {

crates/mako/src/load.rs

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub struct Asset {
2323
pub enum Content {
2424
Js(String),
2525
Css(String),
26+
#[allow(dead_code)]
2627
Assets(Asset),
2728
}
2829

crates/mako/src/parse.rs

+7-39
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,26 @@ use swc_css_ast::Stylesheet;
55
use swc_css_visit::VisitMutWith;
66
use tracing::debug;
77

8-
use crate::ast::{build_css_ast, build_js_ast};
98
use crate::build::FileRequest;
109
use crate::compiler::Context;
11-
use crate::css_modules::{compile_css_modules, generate_code_for_css_modules, is_css_modules_path};
12-
use crate::load::{Asset, Content};
10+
use crate::load::Content;
1311
use crate::module::ModuleAst;
12+
use crate::plugin::PluginParseParam;
1413

1514
pub fn parse(
1615
content: &Content,
1716
request: &FileRequest,
1817
context: &Arc<Context>,
1918
) -> Result<ModuleAst> {
2019
debug!("parse {:?}", request);
21-
let ast = match content {
22-
Content::Js(content) => parse_js(content, request, context)?,
23-
Content::Css(content) => parse_css(content, request, context)?,
24-
Content::Assets(asset) => parse_asset(asset, request, context)?,
25-
};
20+
let ast = context
21+
.plugin_driver
22+
.parse(&PluginParseParam { request, content }, context)?
23+
.unwrap();
2624
Ok(ast)
2725
}
2826

29-
fn parse_js(content: &str, request: &FileRequest, context: &Arc<Context>) -> Result<ModuleAst> {
30-
let ast = build_js_ast(&request.path, content, context)?;
31-
Ok(ModuleAst::Script(ast))
32-
}
33-
34-
fn parse_css(content: &str, request: &FileRequest, context: &Arc<Context>) -> Result<ModuleAst> {
35-
let mut ast = build_css_ast(&request.path, content, context)?;
36-
let is_modules = request.has_query("modules");
37-
// parse css module as js
38-
if is_css_modules_path(&request.path) && !is_modules {
39-
let code = generate_code_for_css_modules(&request.path, &mut ast);
40-
let js_ast = build_js_ast(&request.path, &code, context)?;
41-
Ok(ModuleAst::Script(js_ast))
42-
} else {
43-
// TODO: move to transform step
44-
// compile css compat
45-
compile_css_compat(&mut ast);
46-
// for mako css module, compile it and parse it as css
47-
if is_modules {
48-
compile_css_modules(&request.path, &mut ast);
49-
}
50-
Ok(ModuleAst::Css(ast))
51-
}
52-
}
53-
54-
fn parse_asset(asset: &Asset, request: &FileRequest, context: &Arc<Context>) -> Result<ModuleAst> {
55-
let ast = build_js_ast(&request.path, &asset.content, context)?;
56-
Ok(ModuleAst::Script(ast))
57-
}
58-
59-
fn compile_css_compat(ast: &mut Stylesheet) {
27+
pub fn compile_css_compat(ast: &mut Stylesheet) {
6028
ast.visit_mut_with(&mut swc_css_compat::compiler::Compiler::new(
6129
swc_css_compat::compiler::Config {
6230
process: swc_css_compat::feature::Features::NESTING,

crates/mako/src/plugin.rs

+27
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@ use std::sync::Arc;
33

44
use anyhow::Result;
55

6+
use crate::build::FileRequest;
67
use crate::compiler::Context;
78
use crate::config::Config;
89
use crate::load::Content;
10+
use crate::module::ModuleAst;
911

1012
pub struct PluginLoadParam {
1113
pub path: String,
1214
pub is_entry: bool,
1315
pub ext_name: String,
1416
}
1517

18+
pub struct PluginParseParam<'a> {
19+
pub request: &'a FileRequest,
20+
pub content: &'a Content,
21+
}
22+
1623
pub trait Plugin: Any + Send + Sync {
1724
fn name(&self) -> &str;
1825
fn modify_config(&self, _config: &mut Config) -> Result<()> {
@@ -21,6 +28,13 @@ pub trait Plugin: Any + Send + Sync {
2128
fn load(&self, _param: &PluginLoadParam, _context: &Arc<Context>) -> Result<Option<Content>> {
2229
Ok(None)
2330
}
31+
fn parse(
32+
&self,
33+
_param: &PluginParseParam,
34+
_context: &Arc<Context>,
35+
) -> Result<Option<ModuleAst>> {
36+
Ok(None)
37+
}
2438
}
2539

2640
#[derive(Default)]
@@ -46,4 +60,17 @@ impl PluginDriver {
4660
}
4761
Ok(None)
4862
}
63+
pub fn parse(
64+
&self,
65+
param: &PluginParseParam,
66+
context: &Arc<Context>,
67+
) -> Result<Option<ModuleAst>> {
68+
for plugin in &self.plugins {
69+
let ret = plugin.parse(param, context)?;
70+
if ret.is_some() {
71+
return Ok(ret);
72+
}
73+
}
74+
Ok(None)
75+
}
4976
}

crates/mako/src/plugins/css.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ use std::sync::Arc;
22

33
use anyhow::Result;
44

5+
use crate::ast::{build_css_ast, build_js_ast};
56
use crate::compiler::Context;
7+
use crate::css_modules::{compile_css_modules, generate_code_for_css_modules, is_css_modules_path};
68
use crate::load::{read_content, Content};
7-
use crate::plugin::{Plugin, PluginLoadParam};
9+
use crate::module::ModuleAst;
10+
use crate::parse::compile_css_compat;
11+
use crate::plugin::{Plugin, PluginLoadParam, PluginParseParam};
812

913
pub struct CSSPlugin {}
1014

@@ -19,4 +23,28 @@ impl Plugin for CSSPlugin {
1923
}
2024
Ok(None)
2125
}
26+
27+
fn parse(&self, param: &PluginParseParam, context: &Arc<Context>) -> Result<Option<ModuleAst>> {
28+
if let Content::Css(content) = param.content {
29+
// return Ok(Some(ModuleAst::Css(param.request.clone())));
30+
let mut ast = build_css_ast(&param.request.path, content, context)?;
31+
let is_modules = param.request.has_query("modules");
32+
// parse css module as js
33+
if is_css_modules_path(&param.request.path) && !is_modules {
34+
let code = generate_code_for_css_modules(&param.request.path, &mut ast);
35+
let js_ast = build_js_ast(&param.request.path, &code, context)?;
36+
return Ok(Some(ModuleAst::Script(js_ast)));
37+
} else {
38+
// TODO: move to transform step
39+
// compile css compat
40+
compile_css_compat(&mut ast);
41+
// for mako css module, compile it and parse it as css
42+
if is_modules {
43+
compile_css_modules(&param.request.path, &mut ast);
44+
}
45+
return Ok(Some(ModuleAst::Css(ast)));
46+
}
47+
}
48+
Ok(None)
49+
}
2250
}

crates/mako/src/plugins/javascript.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ use std::sync::Arc;
22

33
use anyhow::Result;
44

5+
use crate::ast::build_js_ast;
56
use crate::compiler::Context;
67
use crate::config::Mode;
78
use crate::load::{read_content, Content};
8-
use crate::plugin::{Plugin, PluginLoadParam};
9+
use crate::module::ModuleAst;
10+
use crate::plugin::{Plugin, PluginLoadParam, PluginParseParam};
911

1012
pub struct JavaScriptPlugin {}
1113

@@ -37,4 +39,12 @@ impl Plugin for JavaScriptPlugin {
3739
}
3840
Ok(None)
3941
}
42+
43+
fn parse(&self, param: &PluginParseParam, context: &Arc<Context>) -> Result<Option<ModuleAst>> {
44+
if let Content::Js(content) = param.content {
45+
let ast = build_js_ast(&param.request.path, content, context)?;
46+
return Ok(Some(ModuleAst::Script(ast)));
47+
}
48+
Ok(None)
49+
}
4050
}

crates/mako/src/plugins/wasm.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::Arc;
33
use anyhow::Result;
44

55
use crate::compiler::Context;
6-
use crate::load::{content_hash, Asset, Content};
6+
use crate::load::{content_hash, Content};
77
use crate::plugin::{Plugin, PluginLoadParam};
88

99
pub struct WASMPlugin {}
@@ -19,13 +19,10 @@ impl Plugin for WASMPlugin {
1919
let final_file_name =
2020
content_hash(param.path.as_str())? + "." + param.ext_name.as_str();
2121
context.emit_assets(param.path.clone(), final_file_name.clone());
22-
return Ok(Some(Content::Assets(Asset {
23-
path: param.path.clone(),
24-
content: format!(
25-
"module.exports = require._interopreRequireWasm(exports, \"{}\")",
26-
final_file_name
27-
),
28-
})));
22+
return Ok(Some(Content::Js(format!(
23+
"module.exports = require._interopreRequireWasm(exports, \"{}\")",
24+
final_file_name
25+
))));
2926
}
3027
Ok(None)
3128
}

crates/mako/test/compile/load/big.jpg

1.19 MB
Loading

crates/mako/test/compile/load/foo.css

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
.foo {
22
color: red;
33
}
4+
5+
.big { background: url("./big.jpg"); }
6+
.small { background: url("./small.png"); }

crates/mako/test/compile/load/index.ts

+12
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,15 @@ import './foo.css';
1414

1515
import toml from './foo.toml';
1616
console.log(toml);
17+
18+
import jpgBig from './big.jpg';
19+
import pngSmall from './small.png';
20+
console.log(jpgBig);
21+
console.log(pngSmall);
22+
23+
import svg from './umi.svg';
24+
console.log(svg);
25+
import { ReactComponent } from './umi.svg';
26+
console.log(ReactComponent);
27+
import x1, { ReactComponent as x2 } from './umi.svg';
28+
console.log(x1, x2);
7.37 KB
Loading

crates/mako/test/compile/load/umi.svg

+1
Loading

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"@swc/helpers": "0.5.1",
99
"husky": "^8.0.3",
1010
"node-libs-browser-okam": "2.2.2",
11+
"react": "^18.2.0",
12+
"react-dom": "^18.2.0",
1113
"react-refresh": "^0.14.0",
1214
"rome": "^12.0.0"
1315
}

0 commit comments

Comments
 (0)