autodetect js module type - only bundle esm (#5515)
* wip: autodetect esm * finish fixes * thread minify through * add sweetalert2 * Fix default bundle types * ts-ignore * small nits * small more nits * shrink flamegraph
This commit is contained in:
1 parent
2f40780ce0
commit
218bb9d56d
24 files changed
+1598
-616
No files matched your search
@@ -63,4 +63,108 @@ for (let { port, name } of test_variants) {
|
||||
);
|
||||
});
|
||||
|
||||
// Regression coverage for https://github.com/DioxusLabs/dioxus/issues/5512.
|
||||
// Both files are vanilla IIFE scripts injected via `with_static_head(true)`.
|
||||
// The 0.7.4–0.7.6 esbuild path wrapped them in a wrapper IIFE / `--format=esm`,
|
||||
// which dropped the global side-effect and produced `export` syntax under a
|
||||
// classic `<script>` tag. The asserted globals only get set if the file is
|
||||
// delivered as a classic script with its body intact.
|
||||
test(`classic js asset with_minify(false) is copied byte-for-byte in ${name}`, async ({ page }) => {
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
// @ts-ignore
|
||||
const value = await page.evaluate(() => window.__iife_classic_value);
|
||||
expect(value).toBe("ok-classic");
|
||||
});
|
||||
|
||||
test(`classic js asset with_minify(true) stays a classic script in ${name}`, async ({ page }) => {
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
// @ts-ignore
|
||||
const value = await page.evaluate(() => window.__iife_minify_value);
|
||||
expect(value).toBe("ok-minify");
|
||||
const classicScript = page.locator('script[src*="iife_minify"]');
|
||||
await expect(classicScript).toHaveCount(1);
|
||||
await expect(classicScript).not.toHaveAttribute("type", "module");
|
||||
});
|
||||
|
||||
test(`umd js asset is minified without being converted to a module in ${name}`, async ({ page }) => {
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
// @ts-ignore
|
||||
const value = await page.evaluate(() => window.__umd_minify_value);
|
||||
expect(value).toBe("ok-umd");
|
||||
const classicScript = page.locator('script[src*="umd_minify"]');
|
||||
await expect(classicScript).toHaveCount(1);
|
||||
await expect(classicScript).not.toHaveAttribute("type", "module");
|
||||
});
|
||||
|
||||
test(`cjs js asset is treated as a classic script in ${name}`, async ({ page }) => {
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
// @ts-ignore
|
||||
const value = await page.evaluate(() => window.__cjs_classic_value);
|
||||
expect(value).toBe("ok-cjs");
|
||||
const classicScript = page.locator('script[src*="cjs_classic"]');
|
||||
await expect(classicScript).toHaveCount(1);
|
||||
await expect(classicScript).not.toHaveAttribute("type", "module");
|
||||
});
|
||||
|
||||
test(`sweetalert2 UMD bundle from issue 5512 is copied and exported globally in ${name}`, async ({ page }) => {
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
// @ts-ignore
|
||||
const value = await page.evaluate(() => ({
|
||||
// @ts-ignore
|
||||
hasGlobal: typeof window.Sweetalert2 === "function",
|
||||
// @ts-ignore
|
||||
hasFire: typeof window.Sweetalert2?.fire === "function",
|
||||
}));
|
||||
expect(value).toEqual({ hasGlobal: true, hasFire: true });
|
||||
const classicScript = page.locator('script[src*="sweetalert2.all.min"]');
|
||||
await expect(classicScript).toHaveCount(1);
|
||||
await expect(classicScript).not.toHaveAttribute("type", "module");
|
||||
});
|
||||
|
||||
// `with_module(true)` should emit `<script type="module">` and preserve
|
||||
// module syntax during minification. The fixture uses `import.meta.url`,
|
||||
// which only parses when the script tag has `type="module"`.
|
||||
test(`js asset with_module(true) is loaded as an ES module in ${name}`, async ({ page }) => {
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
// @ts-ignore
|
||||
const value = await page.evaluate(() => window.__esm_module_value);
|
||||
expect(value).toBe("ok-module");
|
||||
const moduleScript = page.locator('script[type="module"][src*="esm_module"]');
|
||||
await expect(moduleScript).toHaveCount(1);
|
||||
});
|
||||
|
||||
// Auto-detection: the CLI's has_module_syntax scan should recognise top-level
|
||||
// `export` and emit `<script type="module">` even without `with_module(true)`.
|
||||
test(`js asset with top-level export is auto-detected as ES module in ${name}`, async ({ page }) => {
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
// @ts-ignore
|
||||
const value = await page.evaluate(() => window.__esm_auto_value);
|
||||
expect(value).toBe("ok-auto");
|
||||
// import.meta only parses inside a real module; if the script were emitted
|
||||
// as classic the file would have errored at parse time.
|
||||
// @ts-ignore
|
||||
const metaType = await page.evaluate(() => window.__esm_auto_meta);
|
||||
expect(metaType).toBe("string");
|
||||
const moduleScript = page.locator('script[type="module"][src*="esm_auto"]');
|
||||
await expect(moduleScript).toHaveCount(1);
|
||||
});
|
||||
|
||||
test(`js asset with relative ESM import is bundled as an ES module in ${name}`, async ({ page }) => {
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
// @ts-ignore
|
||||
const value = await page.evaluate(() => window.__esm_import_value);
|
||||
expect(value).toBe("ok-esm-import");
|
||||
const moduleScript = page.locator('script[type="module"][src*="esm_import_entry"]');
|
||||
await expect(moduleScript).toHaveCount(1);
|
||||
});
|
||||
|
||||
test(`mjs extension is loaded as an ES module in ${name}`, async ({ page }) => {
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
// @ts-ignore
|
||||
const value = await page.evaluate(() => window.__mjs_auto_value);
|
||||
expect(value).toBe("ok-mjs");
|
||||
const moduleScript = page.locator('script[type="module"][src*="mjs_auto"]');
|
||||
await expect(moduleScript).toHaveCount(1);
|
||||
});
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user