Skip to content

Commit

Permalink
fix(optimizer): let the bundler handle entries
Browse files Browse the repository at this point in the history
- removes entry creating from optimizer
- adds manualChunks option that tells Rollup which chunks to put together
- removes building at buildStart so other plugins can transform before the segment splitting
  • Loading branch information
wmertens committed Aug 1, 2024
1 parent 7b2ee07 commit 568132c
Show file tree
Hide file tree
Showing 15 changed files with 113 additions and 446 deletions.
5 changes: 5 additions & 0 deletions .changeset/ninety-weeks-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@builder.io/qwik': minor
---

The optimizer plugin will now rely on Rollup to group QRL segments. It will only provide hints on which segments fit well together. The result of this change is that now code splitting happens during the transform phase only, and other Rollup/Vite plugins (such as css-in-js plugins) can transform the code before Qwik transforms it.
156 changes: 3 additions & 153 deletions packages/qwik/src/optimizer/core/src/code_move.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
use crate::collector::{new_ident_from_id, GlobalCollect, Id, ImportKind};
use crate::parse::{
emit_source_code, might_need_handle_watch, HookAnalysis, PathData, TransformModule,
TransformOutput,
};
use crate::parse::PathData;
use crate::transform::{add_handle_watch, create_synthetic_named_import};
use crate::words::*;

use std::collections::BTreeMap;
use std::path::Path;

use anyhow::{Context, Error};
use path_slash::PathExt;
use anyhow::Error;
use swc_atoms::JsWord;
use swc_common::comments::{SingleThreadedComments, SingleThreadedCommentsMap};
use swc_common::{sync::Lrc, SourceMap, DUMMY_SP};
use swc_common::DUMMY_SP;
use swc_ecmascript::ast;
use swc_ecmascript::utils::private_ident;

Expand Down Expand Up @@ -158,32 +151,6 @@ pub fn new_module(ctx: NewModuleCtx) -> Result<(ast::Module, SingleThreadedComme
Ok((module, comments))
}

pub fn fix_path<S: AsRef<Path>, D: AsRef<Path>>(
src: S,
dest: D,
ident: &str,
) -> Result<JsWord, Error> {
let src = src.as_ref();
let dest = dest.as_ref();
if ident.starts_with('.') {
let diff = pathdiff::diff_paths(src, dest);

if let Some(diff) = diff {
let normalize = diff.to_slash_lossy();
let relative = relative_path::RelativePath::new(&normalize);
let final_path = relative.join(ident).normalize();
let final_str = final_path.as_str();
return Ok(if final_str.starts_with('.') {
JsWord::from(final_str)
} else {
JsWord::from(format!("./{}", final_str))
});
}
}

Ok(JsWord::from(ident))
}

fn create_named_export(expr: Box<ast::Expr>, name: &str) -> ast::ModuleItem {
ast::ModuleItem::ModuleDecl(ast::ModuleDecl::ExportDecl(ast::ExportDecl {
span: DUMMY_SP,
Expand All @@ -206,123 +173,6 @@ fn create_named_export(expr: Box<ast::Expr>, name: &str) -> ast::ModuleItem {
}))
}

#[test]
fn test_fix_path() {
assert_eq!(
fix_path("src", "", "./state.qwik.mjs").unwrap(),
JsWord::from("./src/state.qwik.mjs")
);

assert_eq!(
fix_path("src/path", "", "./state").unwrap(),
JsWord::from("./src/path/state")
);

assert_eq!(
fix_path("src", "", "../state").unwrap(),
JsWord::from("./state")
);
assert_eq!(
fix_path("a", "a", "./state").unwrap(),
JsWord::from("./state")
);
}

pub fn generate_entries(
mut output: TransformOutput,
core_module: &JsWord,
explicit_extensions: bool,
root_dir: Option<&Path>,
) -> Result<TransformOutput, anyhow::Error> {
let source_map = Lrc::new(SourceMap::default());
let mut entries_map: BTreeMap<&str, Vec<&HookAnalysis>> = BTreeMap::new();
let mut new_modules = Vec::with_capacity(output.modules.len());
{
let hooks: Vec<&HookAnalysis> = output.modules.iter().flat_map(|m| &m.hook).collect();
for hook in hooks {
if let Some(ref e) = hook.entry {
entries_map.entry(e.as_ref()).or_default().push(hook);
}
}

for (entry, hooks) in &entries_map {
let module = new_entry_module(entry, hooks, core_module, explicit_extensions);
let (code, map) =
emit_source_code(Lrc::clone(&source_map), None, &module, root_dir, false)
.context("Emitting source code")?;
new_modules.push(TransformModule {
path: [entry, ".js"].concat(),
code,
map,
is_entry: true,
hook: None,
order: 0,
});
}
}
output.modules.append(&mut new_modules);

Ok(output)
}

fn new_entry_module(
path: &str,
hooks: &[&HookAnalysis],
core_module: &JsWord,
explicit_extensions: bool,
) -> ast::Module {
let mut module = ast::Module {
span: DUMMY_SP,
body: Vec::with_capacity(hooks.len()),
shebang: None,
};
let mut need_handle_watch = false;
for hook in hooks {
// TODO fix the path from the entry to the hook in case of mismatched location
let mut src = fix_path(
hook.path.to_string(),
Path::new(path).parent().unwrap().to_str().unwrap(),
&["./", &hook.canonical_filename].concat(),
)
.unwrap()
.to_string();
if explicit_extensions {
src = src + "." + hook.extension.as_ref();
}
if might_need_handle_watch(&hook.ctx_kind, &hook.ctx_name) {
need_handle_watch = true;
}
module
.body
.push(ast::ModuleItem::ModuleDecl(ast::ModuleDecl::ExportNamed(
ast::NamedExport {
span: DUMMY_SP,
type_only: false,
with: None,
src: Some(Box::new(ast::Str {
span: DUMMY_SP,
value: JsWord::from(src),
raw: None,
})),
specifiers: vec![ast::ExportSpecifier::Named(ast::ExportNamedSpecifier {
is_type_only: false,
span: DUMMY_SP,
orig: ast::ModuleExportName::Ident(ast::Ident::new(
hook.name.clone(),
DUMMY_SP,
Default::default(),
)),
exported: None,
})],
},
)));
}
if need_handle_watch {
add_handle_watch(&mut module.body, core_module);
}
module
}

pub fn transform_function_expr(
expr: ast::Expr,
use_lexical_scope: &Id,
Expand Down
36 changes: 1 addition & 35 deletions packages/qwik/src/optimizer/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ use std::path::Path;
use std::str;
use swc_atoms::JsWord;

use crate::code_move::generate_entries;
use crate::entry_strategy::parse_entry_strategy;
pub use crate::entry_strategy::EntryStrategy;
pub use crate::parse::EmitMode;
Expand Down Expand Up @@ -160,23 +159,7 @@ pub fn transform_fs(config: TransformFsOptions) -> Result<TransformOutput, Error
.reduce(|| Ok(TransformOutput::new()), |x, y| Ok(x?.append(&mut y?)))?;

final_output.modules.sort_unstable_by_key(|key| key.order);
if !matches!(
config.entry_strategy,
EntryStrategy::Hook | EntryStrategy::Inline | EntryStrategy::Hoist
) {
final_output = generate_entries(
final_output,
&core_module,
config.explicit_extensions,
root_dir,
)?;
}
// final_output = generate_entries(
// final_output,
// &core_module,
// config.explicit_extensions,
// root_dir,
// )?;

Ok(final_output)
}

Expand Down Expand Up @@ -231,23 +214,6 @@ pub fn transform_modules(config: TransformModulesOptions) -> Result<TransformOut

let mut final_output = final_output?;
final_output.modules.sort_unstable_by_key(|key| key.order);
if !matches!(
config.entry_strategy,
EntryStrategy::Hook | EntryStrategy::Inline | EntryStrategy::Hoist
) {
final_output = generate_entries(
final_output,
&core_module,
config.explicit_extensions,
root_dir,
)?;
}
// final_output = generate_entries(
// final_output,
// &core_module,
// config.explicit_extensions,
// root_dir,
// )?;

Ok(final_output)
}
4 changes: 1 addition & 3 deletions packages/qwik/src/optimizer/core/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ pub fn transform_code(config: TransformCodeOptions) -> Result<TransformOutput, a
]
.concat();
let need_handle_watch =
might_need_handle_watch(&h.data.ctx_kind, &h.data.ctx_name) && is_entry;
might_need_handle_watch(&h.data.ctx_kind, &h.data.ctx_name);

let (mut hook_module, comments) = new_module(NewModuleCtx {
expr: h.expr,
Expand Down Expand Up @@ -676,7 +676,6 @@ fn handle_error(
pub struct PathData {
pub abs_path: PathBuf,
pub rel_path: PathBuf,
pub base_dir: PathBuf,
pub abs_dir: PathBuf,
pub rel_dir: PathBuf,
pub file_stem: String,
Expand Down Expand Up @@ -706,7 +705,6 @@ pub fn parse_path(src: &str, base_dir: &Path) -> Result<PathData, Error> {

Ok(PathData {
abs_path,
base_dir: base_dir.to_path_buf(),
rel_path: path.into(),
abs_dir,
rel_dir,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const App = component$(() => {

import dep3 from "dep3/something";
export const Header_component_Header_onClick_KjD9TCNkNxY = (ev)=>dep3(ev);
export { _hW } from "@builder.io/qwik";


Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";2DAQ2B,CAAC,KAAO,KAAK\"}")
Expand Down Expand Up @@ -59,13 +60,13 @@ import { bar as bbar } from "../state";
import * as dep2 from "dep2";
import { qrl } from "@builder.io/qwik";
export const Header_component_UVBJuFYfvDo = ()=>{
return <Header onClick={/*#__PURE__*/ qrl(()=>import("../entry_hooks"), "Header_component_Header_onClick_KjD9TCNkNxY")}>
return <Header onClick={/*#__PURE__*/ qrl(()=>import("./header_component_header_onclick_kjd9tcnknxy"), "Header_component_Header_onClick_KjD9TCNkNxY")}>
{dep2.stuff()}{bbar()}
</Header>;
};


Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;;;4CAMiC;IAC7B,QACK,OAAO,yGAA8B;YAClC,CAAC,KAAK,KAAK,IAAI,OAAO;QAC1B,EAAE;AAEV\"}")
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;;;4CAMiC;IAC7B,QACK,OAAO,wIAA8B;YAClC,CAAC,KAAK,KAAK,IAAI,OAAO;QAC1B,EAAE;AAEV\"}")
/*
{
"origin": "project/test.tsx",
Expand Down Expand Up @@ -120,20 +121,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\"

import { componentQrl } from "@builder.io/qwik";
import { qrl } from "@builder.io/qwik";
export const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("../entry_hooks"), "Header_component_UVBJuFYfvDo"));
export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("../entry_hooks"), "App_component_wGkRHWXaqjs"));


Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;AAMA,OAAO,MAAM,uBAAS,8FAMnB;AAEH,OAAO,MAAM,oBAAM,2FAIhB\"}")
============================= entry_hooks.js (ENTRY POINT)==

export { Header_component_Header_onClick_KjD9TCNkNxY } from "./project/header_component_header_onclick_kjd9tcnknxy";
export { Header_component_UVBJuFYfvDo } from "./project/header_component_uvbjufyfvdo";
export { App_component_wGkRHWXaqjs } from "./project/app_component_wgkrhwxaqjs";
export { _hW } from "@builder.io/qwik";
export const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./header_component_uvbjufyfvdo"), "Header_component_UVBJuFYfvDo"));
export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./app_component_wgkrhwxaqjs"), "App_component_wGkRHWXaqjs"));


None
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;AAMA,OAAO,MAAM,uBAAS,8GAMnB;AAEH,OAAO,MAAM,oBAAM,wGAIhB\"}")
== DIAGNOSTICS ==

[]
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export default component$(() => {

import { componentQrl } from "@builder.io/qwik";
import { qrl } from "@builder.io/qwik";
export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("../../../../src/routes/_repl/[id]/[[...slug]].tsx_entry_[[...slug]].js"), "slug_component_0AM8HPnkNs4"));
export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./slug_component_0am8hpnkns4.js"), "slug_component_0AM8HPnkNs4"));


Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/routes/_repl/[id]/[[...slug]].tsx\"],\"names\":[],\"mappings\":\";;AAIA,6BAAe,oJAKZ\"}")
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/routes/_repl/[id]/[[...slug]].tsx\"],\"names\":[],\"mappings\":\";;AAIA,6BAAe,6GAKZ\"}")
============================= src/routes/_repl/[id]/slug_component_div_onclick_xevvy0qc7pa.js (ENTRY POINT)==

import { sibling } from "./sibling";
Expand Down Expand Up @@ -84,12 +84,6 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/routes/_repl/[id]/[[...sl
]
}
*/
============================= src/routes/_repl/[id]/[[...slug]].tsx_entry_[[...slug]].js (ENTRY POINT)==

export { slug_component_0AM8HPnkNs4 } from "./slug_component_0am8hpnkns4.js";


None
== DIAGNOSTICS ==

[]
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export const App = component$((props) => {

import { componentQrl } from "@builder.io/qwik";
import { qrl } from "@builder.io/qwik";
export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./entry_hooks.tsx"), "App_component_ckEPmXZlub0"));
export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./app_component_ckepmxzlub0.tsx"), "App_component_ckEPmXZlub0"));


Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,8FAKhB\"}")
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,4GAKhB\"}")
============================= app_component_usestyles_t35nsa5uv7u.tsx ==

export const App_component_useStyles_t35nSa5UV7U = 'hola';
Expand Down Expand Up @@ -54,8 +54,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
import { qrl } from "@builder.io/qwik";
import { useStylesQrl } from "@builder.io/qwik";
export const App_component_ckEPmXZlub0 = (props)=>{
useStylesQrl(/*#__PURE__*/ qrl(()=>import("./entry_hooks.tsx"), "App_component_useStyles_t35nSa5UV7U"));
return /*#__PURE__*/ qrl(()=>import("./entry_hooks.tsx"), "App_component_1_w0t0o3QMovU");
useStylesQrl(/*#__PURE__*/ qrl(()=>import("./app_component_usestyles_t35nsa5uv7u.tsx"), "App_component_useStyles_t35nSa5UV7U"));
return /*#__PURE__*/ qrl(()=>import("./app_component_1_w0t0o3qmovu.tsx"), "App_component_1_w0t0o3QMovU");
};


Expand Down Expand Up @@ -83,6 +83,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
============================= app_component_1_w0t0o3qmovu.tsx ==

export const App_component_1_w0t0o3QMovU = ()=><div></div>;
export { _hW } from "@builder.io/qwik";


Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"2CAKa,KACJ,MAAM\"}")
Expand All @@ -106,15 +107,6 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
]
}
*/
============================= entry_hooks.js (ENTRY POINT)==

export { App_component_useStyles_t35nSa5UV7U } from "./app_component_usestyles_t35nsa5uv7u.tsx";
export { App_component_ckEPmXZlub0 } from "./app_component_ckepmxzlub0.tsx";
export { App_component_1_w0t0o3QMovU } from "./app_component_1_w0t0o3qmovu.tsx";
export { _hW } from "@builder.io/qwik";


None
== DIAGNOSTICS ==

[]
Loading

0 comments on commit 568132c

Please sign in to comment.