Skip to content

Commit

Permalink
feat: support targetEnv library library-browser/node (#1656)
Browse files Browse the repository at this point in the history
  • Loading branch information
wre232114 authored Jul 23, 2024
1 parent 29a4820 commit fcd4dc3
Show file tree
Hide file tree
Showing 22 changed files with 228 additions and 58 deletions.
9 changes: 9 additions & 0 deletions .changeset/tricky-jobs-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@farmfe/core": patch
"@farmfe/cli": patch
---

- Mark farm compatible with node 16
- Support targetEnv `library-node` and `library-browser`
- fix watcher does not watch file change beyond the project root
- remove script bundle port conflict log when lazy compile is disabled
53 changes: 53 additions & 0 deletions crates/core/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,30 @@ pub enum TargetEnv {
Browser,
#[serde(rename = "node")]
Node,
/// [TargetEnv::Library] is alias of [TargetEnv::Custom("library-browser")]
#[serde(rename = "library")]
Library,
#[serde(untagged)]
Custom(String),
}

impl TargetEnv {
pub fn is_browser(&self) -> bool {
matches!(self, TargetEnv::Browser | TargetEnv::Library)
|| matches!(self, TargetEnv::Custom(custom) if custom == "library-browser")
}

pub fn is_node(&self) -> bool {
matches!(self, TargetEnv::Node)
|| matches!(self, TargetEnv::Custom(custom) if custom == "library-node")
}

pub fn is_library(&self) -> bool {
matches!(self, TargetEnv::Library)
|| matches!(self, TargetEnv::Custom(custom) if custom == "library-browser" || custom == "library-node")
}
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Hash, Default)]
pub enum ModuleFormat {
#[serde(rename = "esm")]
Expand Down Expand Up @@ -355,4 +374,38 @@ mod tests {

assert!(matches!(config, SourcemapConfig::All));
}

#[test]
fn target_env() {
use super::TargetEnv;
let env = TargetEnv::Browser;
assert!(env.is_browser());
assert!(!env.is_node());
assert!(!env.is_library());

let env = TargetEnv::Node;
assert!(env.is_node());
assert!(!env.is_browser());
assert!(!env.is_library());

let env = TargetEnv::Library;
assert!(env.is_library());
assert!(!env.is_node());
assert!(env.is_browser());

let env = TargetEnv::Custom("library-browser".to_string());
assert!(env.is_library());
assert!(!env.is_node());
assert!(env.is_browser());

let env = TargetEnv::Custom("library-node".to_string());
assert!(env.is_library());
assert!(env.is_node());
assert!(!env.is_browser());

let env: TargetEnv = serde_json::from_str("\"library-browser\"").expect("failed to parse");
assert!(env.is_library());
assert!(!env.is_node());
assert!(env.is_browser());
}
}
88 changes: 76 additions & 12 deletions crates/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use std::path::PathBuf;
use std::{collections::HashMap, path::Path, sync::Arc};

use farmfe_compiler::Compiler;
use farmfe_compiler::{trace_module_graph::TracedModuleGraph, Compiler};

pub mod plugin_adapters;
pub mod plugin_toolkit;
Expand Down Expand Up @@ -48,6 +48,42 @@ pub struct WatchDiffResult {
pub remove: Vec<String>,
}

#[napi(object)]
pub struct JsTracedModule {
pub id: String,
pub content_hash: String,
pub package_name: String,
pub package_version: String,
}

#[napi(object)]
pub struct JsTracedModuleGraph {
pub root: String,
pub modules: Vec<JsTracedModule>,
pub edges: HashMap<String, Vec<String>>,
pub reverse_edges: HashMap<String, Vec<String>>,
}

impl From<TracedModuleGraph> for JsTracedModuleGraph {
fn from(t: TracedModuleGraph) -> Self {
Self {
root: t.root,
modules: t
.modules
.into_iter()
.map(|m| JsTracedModule {
id: m.id,
content_hash: m.content_hash,
package_name: m.package_name,
package_version: m.package_version,
})
.collect(),
edges: t.edges,
reverse_edges: t.reverse_edges,
}
}
}

#[napi(object)]
pub struct JsUpdateResult {
pub added: Vec<String>,
Expand Down Expand Up @@ -206,21 +242,49 @@ impl JsCompiler {
}

#[napi]
pub fn trace_dependencies(&self) -> napi::Result<Vec<String>> {
self
.compiler
.trace_dependencies()
.map_err(|e| napi::Error::new(Status::GenericFailure, format!("{}", e)))
pub fn trace_dependencies(&self, e: Env) -> napi::Result<JsObject> {
let (promise, result) =
e.create_deferred::<Vec<String>, Box<dyn FnOnce(Env) -> napi::Result<Vec<String>>>>()?;

let compiler = self.compiler.clone();
self.compiler.thread_pool.spawn(move || {
match compiler
.trace_dependencies()
.map_err(|e| napi::Error::new(Status::GenericFailure, format!("{}", e)))
{
Ok(deps) => {
promise.resolve(Box::new(|_| Ok(deps)));
}
Err(err) => {
promise.reject(err);
}
}
});

Ok(result)
}

#[napi]
pub fn trace_module_graph(&self, e: Env) -> napi::Result<JsUnknown> {
let graph = self
.compiler
.trace_module_graph()
.map_err(|e| napi::Error::new(Status::GenericFailure, format!("{}", e)))?;
pub fn trace_module_graph(&self, e: Env) -> napi::Result<JsObject> {
let (promise, result) =
e.create_deferred::<JsTracedModuleGraph, Box<dyn FnOnce(Env) -> napi::Result<JsTracedModuleGraph>>>()?;

let compiler = self.compiler.clone();
self.compiler.thread_pool.spawn(move || {
match compiler
.trace_module_graph()
.map_err(|e| napi::Error::new(Status::GenericFailure, format!("{}", e)))
{
Ok(graph) => {
promise.resolve(Box::new(|_| Ok(graph.into())));
}
Err(err) => {
promise.reject(err);
}
}
});

e.to_js_value(&graph)
Ok(result)
}

/// async compile, return promise
Expand Down
2 changes: 1 addition & 1 deletion crates/plugin_bundle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl Plugin for FarmPluginBundle {
let mut defer_minify = vec![];
for resource_pot in resource_pots.iter() {
if matches!(resource_pot.resource_pot_type, ResourcePotType::Runtime)
|| (context.config.output.target_env == TargetEnv::Library
|| (context.config.output.target_env.is_library()
&& resource_pot.resource_pot_type == ResourcePotType::Js)
{
let resource_pot_id = resource_pot.id.clone();
Expand Down
6 changes: 3 additions & 3 deletions crates/plugin_resolve/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl Resolver {
context: &Arc<CompilationContext>,
) -> Option<PluginResolveHookResult> {
farm_profile_function!("try_browser".to_string());
if context.config.output.target_env != TargetEnv::Browser {
if !context.config.output.target_env.is_browser() {
return None;
}

Expand Down Expand Up @@ -650,7 +650,7 @@ impl Resolver {
resolve_exports_or_imports(&package_json_info, subpath, "exports", kind, context)
.map(|resolve_exports_path| resolve_exports_path.get(0).unwrap().to_string())
.or_else(|| {
if context.config.output.target_env == TargetEnv::Browser {
if context.config.output.target_env.is_browser() {
try_browser_map(
&package_json_info,
BrowserMapType::Source(subpath.to_string()),
Expand Down Expand Up @@ -716,7 +716,7 @@ impl Resolver {
.main_fields
.iter()
.find_map(|main_field| {
if main_field == "browser" && context.config.output.target_env == TargetEnv::Node {
if main_field == "browser" && !context.config.output.target_env.is_browser() {
return None;
}
raw_package_json_info
Expand Down
2 changes: 1 addition & 1 deletion crates/plugin_resolve/src/resolver/exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub fn resolve_exports_or_imports(
}

// resolve exports field
let is_browser = context.config.output.target_env == TargetEnv::Browser;
let is_browser = context.config.output.target_env.is_browser();
let is_require = match kind {
ResolveKind::Require => true,
_ => false,
Expand Down
7 changes: 4 additions & 3 deletions crates/plugin_runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ impl Plugin for FarmPluginRuntime {
}

fn config(&self, config: &mut Config) -> farmfe_core::error::Result<Option<()>> {
if config.output.target_env == TargetEnv::Library {
// library bundle does not contain runtime
if config.output.target_env.is_library() {
return Ok(None);
}

Expand Down Expand Up @@ -269,7 +270,7 @@ impl Plugin for FarmPluginRuntime {
context: &Arc<CompilationContext>,
_hook_context: &PluginHookContext,
) -> farmfe_core::error::Result<Option<ResourcePotMetaData>> {
if context.config.output.target_env != TargetEnv::Library
if !context.config.output.target_env.is_library()
&& matches!(resource_pot.resource_pot_type, ResourcePotType::Js)
{
let async_modules = self.get_async_modules(context);
Expand Down Expand Up @@ -445,7 +446,7 @@ impl Plugin for FarmPluginRuntime {
param: &mut PluginFinalizeResourcesHookParams,
context: &Arc<CompilationContext>,
) -> farmfe_core::error::Result<Option<()>> {
if context.config.output.target_env == TargetEnv::Library {
if context.config.output.target_env.is_library() {
return Ok(None);
}

Expand Down
2 changes: 1 addition & 1 deletion crates/plugin_static_assets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ impl Plugin for FarmPluginStaticAssets {
format!("/{}", resource_name)
};

let content = if matches!(context.config.output.target_env, TargetEnv::Node) {
let content = if context.config.output.target_env.is_node() {
format!(
"export default new URL(/* {} */{:?}, import.meta.url)",
FARM_IGNORE_ACTION_COMMENT, assets_path
Expand Down
8 changes: 4 additions & 4 deletions examples/css-modules/farm.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ function defineConfig(config: UserConfig) {
export default defineConfig({
compilation: {
input: {
index: './index.html',
index: './index.html'
},
output: {
path: './build',
path: './build'
},
record: true,
sourcemap: true
// treeShaking: true,
// minify: true,
},
server: {
open: true,
open: true
},
plugins: ['@farmfe/plugin-react', '@farmfe/plugin-sass', postcss()],
plugins: ['@farmfe/plugin-react', '@farmfe/plugin-sass', postcss()]
});
8 changes: 3 additions & 5 deletions examples/lib-for-browser/farm.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default defineConfig({
format: 'esm',
path: 'dist',
entryFilename: '[entryName].js',
filename: '[name].jsx',
filename: '[name].jsx'
},
minify: false,
presetEnv: false,
Expand All @@ -24,7 +24,5 @@ export default defineConfig({
]
}
},
plugins: [
farmJsPluginDts({})
]
})
plugins: [farmJsPluginDts({})]
});
2 changes: 1 addition & 1 deletion examples/script-entry/farm.config.cjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const config: UserConfig = {
output: {
path: 'dist/cjs',
entryFilename: '[entryName].cjs',
targetEnv: 'library',
targetEnv: 'library-node',
format: 'cjs'
},
lazyCompilation: false,
Expand Down
2 changes: 1 addition & 1 deletion examples/script-entry/farm.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default defineConfig({
output: {
path: 'dist/esm',
entryFilename: '[entryName].mjs',
targetEnv: 'library',
targetEnv: 'library-node',
format: 'esm'
},
presetEnv: false,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"dependencies": {
"cac": "^6.7.14",
"cross-spawn": "^7.0.3",
"inquirer": "^9.1.4",
"inquirer": "9.2.12",
"walkdir": "^0.4.1"
},
"devDependencies": {
Expand Down
16 changes: 14 additions & 2 deletions packages/core/binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ export interface WatchDiffResult {
add: Array<string>
remove: Array<string>
}
export interface JsTracedModule {
id: string
contentHash: string
packageName: string
packageVersion: string
}
export interface JsTracedModuleGraph {
root: string
modules: Array<JsTracedModule>
edges: Record<string, Array<string>>
reverseEdges: Record<string, Array<string>>
}
export interface JsUpdateResult {
added: Array<string>
changed: Array<string>
Expand Down Expand Up @@ -107,8 +119,8 @@ export interface ResourcePotRecord {
export type JsCompiler = Compiler
export declare class Compiler {
constructor(config: object)
traceDependencies(): Array<string>
traceModuleGraph(): unknown
traceDependencies(): object
traceModuleGraph(): object
/** async compile, return promise */
compile(): object
/** sync compile */
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"slashes": "^3.0.12",
"ws": "^8.12.0",
"zod": "^3.23.8",
"zod-validation-error": "^3.3.0"
"zod-validation-error": "^1.3.0"
},
"engines": {
"node": ">=16.15.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ const targetsMap: TargetsMap = {
scriptGenTarget: 'es2017'
},
'browser-esnext': null,
library: null
library: null,
'library-browser': null,
'library-node': null
};

/**
Expand Down
Loading

0 comments on commit fcd4dc3

Please sign in to comment.