Skip to content

Commit c49203b

Browse files
authored
feat: add vite environments api compatibility (#236)
* feat: vite environment api support
1 parent 8c84cc4 commit c49203b

File tree

2 files changed

+84
-4
lines changed

2 files changed

+84
-4
lines changed

.changeset/frank-wings-share.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@marko/vite": minor
3+
---
4+
5+
compatibility with the vite environments api

src/index.ts

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,23 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
203203
{
204204
name: "marko-vite:pre",
205205
enforce: "pre", // Must be pre to allow us to resolve assets before vite.
206+
sharedDuringBuild: true,
207+
async buildApp(builder) {
208+
const { ssr, client } = builder.environments;
209+
if (!ssr || !client) {
210+
// vite on legacy linked build
211+
return;
212+
}
213+
// vite environment api build
214+
if (builder.config?.builder?.buildApp) {
215+
// let custom builder take priority
216+
return;
217+
}
218+
if (linked) {
219+
await builder.build(ssr);
220+
}
221+
await builder.build(client);
222+
},
206223
async config(config, env) {
207224
let optimize = env.mode === "production";
208225
isTest = env.mode === "test";
@@ -412,6 +429,11 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
412429
!isCJSModule(id, rootResolveFile);
413430
}
414431

432+
if (linked && !isSSRBuild) {
433+
config.build ??= {};
434+
config.build.emptyOutDir = false;
435+
}
436+
415437
if (basePathVar) {
416438
config.experimental ??= {};
417439

@@ -468,6 +490,53 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
468490
},
469491
};
470492
},
493+
configEnvironment(name, options) {
494+
if (name === "ssr") {
495+
options.resolve ??= {};
496+
const { noExternal } = options.resolve;
497+
if (noExternal !== true) {
498+
const noExternalReg = /\.marko$/;
499+
if (noExternal) {
500+
if (Array.isArray(noExternal)) {
501+
options.resolve.noExternal = [...noExternal, noExternalReg];
502+
} else {
503+
options.resolve.noExternal = [noExternal, noExternalReg];
504+
}
505+
} else {
506+
options.resolve.noExternal = noExternalReg;
507+
}
508+
}
509+
510+
options.build ??= {};
511+
options.build.emptyOutDir = true;
512+
513+
if (!options.build?.rollupOptions?.output) {
514+
// For the server build vite will still output code split chunks to the `assets` directory by default.
515+
// this is problematic since you might have server assets in your client assets folder.
516+
// Here we change the default chunkFileNames config to instead output to the outDir directly.
517+
options.build.rollupOptions ??= {};
518+
options.build.rollupOptions.output = {
519+
chunkFileNames: `[name]-[hash].js`,
520+
};
521+
}
522+
if (!options.build?.commonjsOptions?.esmExternals) {
523+
// Rollup rewrites `require` calls to default imports for commonjs dependencies; however, if the
524+
// dependency is inlined, its require calls which were assumed to be commonjs are also rewritten but
525+
// now resolve from an ESM context and the default import is no longer safe due to conditional exports.
526+
// This tells Rollup which dependencies are ESM so it uses a namespace import instead.
527+
options.build.commonjsOptions ??= {};
528+
options.build.commonjsOptions.esmExternals = (id) =>
529+
!isCJSModule(id, rootResolveFile);
530+
}
531+
} else {
532+
if (linked) {
533+
options.build ??= {};
534+
options.build.emptyOutDir = false;
535+
}
536+
}
537+
538+
return options;
539+
},
471540
configResolved(config) {
472541
basePath = config.base;
473542
cacheDir = config.cacheDir && normalizePath(config.cacheDir);
@@ -535,7 +604,7 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
535604

536605
async options(inputOptions) {
537606
if (linked && isBuild) {
538-
if (isSSRBuild) {
607+
if (isSSRBuild || this.environment?.name === "ssr") {
539608
serverManifest = {
540609
entries: {},
541610
entrySources: {},
@@ -567,7 +636,12 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
567636
}
568637
},
569638
async buildStart() {
570-
if (isBuild && linked && !isSSRBuild) {
639+
if (
640+
isBuild &&
641+
linked &&
642+
!isSSRBuild &&
643+
this.environment?.name !== "ssr"
644+
) {
571645
for (const assetId of serverManifest!.ssrAssetIds) {
572646
this.load({
573647
id: normalizePath(path.resolve(root, assetId)),
@@ -911,7 +985,8 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
911985
{
912986
name: "marko-vite:post",
913987
apply: "build",
914-
enforce: "post", // We use a "post" plugin to allow us to read the final generated `.html` from vite.
988+
enforce: "post", // We use a "post" plugin to allow us to read the final generated `.html` from vite.,
989+
sharedDuringBuild: true,
915990
transform(_source, id, opts) {
916991
if (!opts?.ssr && /\.module\.[^.]+(?:\?|$)/.test(id)) {
917992
// CSS modules in vite tree shake, however when coupled with
@@ -935,7 +1010,7 @@ export default function markoPlugin(opts: Options = {}): vite.Plugin[] {
9351010
);
9361011
}
9371012

938-
if (isSSRBuild) {
1013+
if (isSSRBuild || this.environment?.name === "ssr") {
9391014
const dir = outputOptions.dir
9401015
? path.resolve(outputOptions.dir)
9411016
: path.resolve(outputOptions.file!, "..");

0 commit comments

Comments
 (0)