@marko/vite 5.3.8 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,38 @@
1
+ import { types as t } from "@marko/compiler";
2
+ /**
3
+ * This plugin is designed to transform imports within Marko files to interop between ESM and CJS.
4
+ * In Node, ESM files cannot reliably use named imports and default imports from CJS files.
5
+ * Additionally, modules which are transpiled from ESM to CJS will use a `__esModule` property to
6
+ * signal that the consuming ESM code should treat `exports.default` as the default import.
7
+ * This plugin only modifies imports it determined to be for CJS modules.
8
+ *
9
+ * Examples:
10
+ * 1. Named imports:
11
+ * Source: import { bar as baz } from 'foo';
12
+ * Becomes: import * as _foo from 'foo';
13
+ * const { bar: baz } = importNS(_foo);
14
+ *
15
+ * 2. Default imports:
16
+ * Source: import myFoo from 'foo';
17
+ * Becomes: import * as _myFoo from 'foo';
18
+ * const { default: myFoo } = importDefault(_myFoo);
19
+ *
20
+ * 3. Namespace imports:
21
+ * Source: import * as nsFoo from 'foo';
22
+ * Becomes: import * as _nsFoo from 'foo';
23
+ * const nsFoo = importNS(_nsFoo);
24
+ *
25
+ * 4. Default and named imports:
26
+ * Source: import myFoo, { bar as baz } from 'foo';
27
+ * Becomes: import * as _foo from 'foo';
28
+ * const { default: myFoo } = importDefault(_foo);
29
+ * const { bar: baz } = importNS(_foo);
30
+ */
31
+ export declare const cjsInteropHelpersId = "\0marko-cjs-interop.js";
32
+ export declare const cjsInteropHelpersCode = "export const importNS = m => m && (m.default === void 0 || m.__esModule ? m : m.default);\nexport const importDefault = m => m?.default?.__esModule ? m.default : m;\n";
33
+ declare const _default: {
34
+ Program: {
35
+ exit(program: t.NodePath<t.Program>): void;
36
+ };
37
+ };
38
+ export default _default;
package/dist/index.mjs CHANGED
@@ -7,8 +7,9 @@ import fs4 from "fs";
7
7
  import { createRequire } from "module";
8
8
  import path6 from "path";
9
9
 
10
- // src/babel-plugin-cjs-interop.ts
11
- import * as t from "@babel/types";
10
+ // src/cjs-interop-translate.ts
11
+ import { types as t } from "@marko/compiler";
12
+ import { importNamed } from "@marko/compiler/babel-utils";
12
13
 
13
14
  // src/resolve.ts
14
15
  import fs from "fs";
@@ -52,134 +53,107 @@ function isCJSModule(id, fromFile) {
52
53
  return isCJS;
53
54
  }
54
55
 
55
- // src/babel-plugin-cjs-interop.ts
56
- function plugin(options) {
57
- return {
58
- name: "marko-import-interop",
59
- visitor: {
60
- ImportDeclaration(path7) {
61
- if (!path7.node.specifiers.length || /\.(?:mjs|marko)$|\?/.test(path7.node.source.value) || options.filter?.(path7.node.source.value) === false || !isCJSModule(
62
- path7.node.source.value,
63
- path7.hub.file.opts.filename
64
- )) {
65
- return;
66
- }
67
- let namespaceId;
68
- let defaultImportId;
69
- let imports;
70
- for (const s of path7.node.specifiers) {
71
- if (t.isImportSpecifier(s)) {
72
- (imports ||= []).push({
73
- name: t.isStringLiteral(s.imported) ? s.imported.value : s.imported.name,
74
- alias: s.local.name
75
- });
76
- } else if (t.isImportDefaultSpecifier(s)) {
77
- defaultImportId = s.local;
78
- } else if (t.isImportNamespaceSpecifier(s)) {
79
- namespaceId = s.local;
80
- }
81
- }
82
- const rawImport = path7.scope.generateUidIdentifier(
83
- namespaceId?.name || defaultImportId?.name || path7.node.source.value
84
- );
85
- path7.node.specifiers = [t.importNamespaceSpecifier(rawImport)];
86
- if (defaultImportId) {
87
- path7.insertAfter(
88
- t.variableDeclaration("const", [
89
- t.variableDeclarator(
90
- t.objectPattern([
91
- t.objectProperty(t.identifier("default"), defaultImportId)
92
- ]),
93
- t.conditionalExpression(
94
- t.optionalMemberExpression(
95
- t.memberExpression(rawImport, t.identifier("default")),
96
- t.identifier("__esModule"),
97
- false,
98
- true
99
- ),
100
- t.memberExpression(rawImport, t.identifier("default")),
101
- rawImport
102
- )
103
- )
104
- ])
105
- );
106
- }
107
- if (namespaceId) {
108
- path7.insertAfter(
109
- t.variableDeclaration("const", [
110
- t.variableDeclarator(
111
- namespaceId,
112
- t.conditionalExpression(
113
- t.logicalExpression(
114
- "||",
115
- t.binaryExpression(
116
- "===",
117
- t.optionalMemberExpression(
118
- rawImport,
119
- t.identifier("default"),
120
- false,
121
- true
122
- ),
123
- t.unaryExpression("void", t.numericLiteral(0), true)
124
- ),
125
- t.optionalMemberExpression(
126
- rawImport,
127
- t.identifier("__esModule"),
128
- false,
129
- true
130
- )
131
- ),
132
- rawImport,
133
- t.memberExpression(rawImport, t.identifier("default"))
134
- )
135
- )
136
- ])
137
- );
138
- }
139
- if (imports) {
140
- path7.insertAfter(
141
- t.variableDeclaration("const", [
142
- t.variableDeclarator(
143
- t.objectPattern(
144
- imports.map(
145
- ({ name, alias }) => t.objectProperty(
146
- t.identifier(name),
147
- t.identifier(alias),
148
- false,
149
- name === alias
150
- )
151
- )
152
- ),
153
- t.conditionalExpression(
154
- t.logicalExpression(
155
- "||",
156
- t.binaryExpression(
157
- "===",
158
- t.optionalMemberExpression(
159
- rawImport,
160
- t.identifier("default"),
161
- false,
162
- true
163
- ),
164
- t.unaryExpression("void", t.numericLiteral(0), true)
165
- ),
166
- t.optionalMemberExpression(
167
- rawImport,
168
- t.identifier("__esModule"),
169
- false,
170
- true
171
- )
172
- ),
173
- rawImport,
174
- t.memberExpression(rawImport, t.identifier("default"))
175
- )
176
- )
177
- ])
178
- );
56
+ // src/cjs-interop-translate.ts
57
+ var cjsInteropHelpersId = "\0marko-cjs-interop.js";
58
+ var cjsInteropHelpersCode = `export const importNS = m => m && (m.default === void 0 || m.__esModule ? m : m.default);
59
+ export const importDefault = m => m?.default?.__esModule ? m.default : m;
60
+ `;
61
+ var cjs_interop_translate_default = {
62
+ Program: {
63
+ exit(program) {
64
+ const { cjsInteropMarkoVite } = program.hub.file.markoOpts;
65
+ if (!cjsInteropMarkoVite) return;
66
+ const { filter } = cjsInteropMarkoVite;
67
+ const children = program.get("body");
68
+ for (let i = children.length; i--; ) {
69
+ const child = children[i];
70
+ if (child.isImportDeclaration()) {
71
+ translateImport(child, filter);
179
72
  }
180
73
  }
181
74
  }
182
- };
75
+ }
76
+ };
77
+ function translateImport(importDecl, filter) {
78
+ if (!importDecl.node.specifiers.length || /\.(?:mjs|marko)$|\?/.test(importDecl.node.source.value) || filter?.(importDecl.node.source.value) === false || !isCJSModule(
79
+ importDecl.node.source.value,
80
+ importDecl.hub.file.opts.filename
81
+ )) {
82
+ return;
83
+ }
84
+ let namespaceId;
85
+ let defaultImportId;
86
+ let imports;
87
+ for (const s of importDecl.node.specifiers) {
88
+ if (t.isImportSpecifier(s)) {
89
+ (imports ||= []).push({
90
+ name: t.isStringLiteral(s.imported) ? s.imported.value : s.imported.name,
91
+ alias: s.local.name
92
+ });
93
+ } else if (t.isImportDefaultSpecifier(s)) {
94
+ defaultImportId = s.local;
95
+ } else if (t.isImportNamespaceSpecifier(s)) {
96
+ namespaceId = s.local;
97
+ }
98
+ }
99
+ const rawImport = importDecl.scope.generateUidIdentifier(
100
+ namespaceId?.name || defaultImportId?.name || importDecl.node.source.value
101
+ );
102
+ importDecl.node.specifiers = [t.importNamespaceSpecifier(rawImport)];
103
+ if (defaultImportId) {
104
+ importDecl.insertAfter(
105
+ t.variableDeclaration("const", [
106
+ t.variableDeclarator(
107
+ t.objectPattern([
108
+ t.objectProperty(t.identifier("default"), defaultImportId)
109
+ ]),
110
+ t.callExpression(
111
+ importNamed(
112
+ importDecl.hub.file,
113
+ cjsInteropHelpersId,
114
+ "importDefault"
115
+ ),
116
+ [rawImport]
117
+ )
118
+ )
119
+ ])
120
+ );
121
+ }
122
+ if (namespaceId) {
123
+ importDecl.insertAfter(
124
+ t.variableDeclaration("const", [
125
+ t.variableDeclarator(
126
+ namespaceId,
127
+ t.callExpression(
128
+ importNamed(importDecl.hub.file, cjsInteropHelpersId, "importNS"),
129
+ [rawImport]
130
+ )
131
+ )
132
+ ])
133
+ );
134
+ }
135
+ if (imports) {
136
+ importDecl.insertAfter(
137
+ t.variableDeclaration("const", [
138
+ t.variableDeclarator(
139
+ t.objectPattern(
140
+ imports.map(
141
+ ({ name, alias }) => t.objectProperty(
142
+ t.identifier(name),
143
+ t.identifier(alias),
144
+ false,
145
+ name === alias
146
+ )
147
+ )
148
+ ),
149
+ t.callExpression(
150
+ importNamed(importDecl.hub.file, cjsInteropHelpersId, "importNS"),
151
+ [rawImport]
152
+ )
153
+ )
154
+ ])
155
+ );
156
+ }
183
157
  }
184
158
 
185
159
  // src/esbuild-plugin.ts
@@ -290,9 +264,9 @@ import { relativeImportPath } from "relative-import-path";
290
264
  var programGlobImports = /* @__PURE__ */ new WeakMap();
291
265
  var glob_import_transform_default = {
292
266
  MetaProperty(tag) {
293
- const memberExpression2 = tag.parentPath;
294
- if (memberExpression2.node.type === "MemberExpression" && memberExpression2.node.property.type === "Identifier" && memberExpression2.node.property.name === "glob") {
295
- const callExpression = memberExpression2.parentPath;
267
+ const memberExpression = tag.parentPath;
268
+ if (memberExpression.node.type === "MemberExpression" && memberExpression.node.property.type === "Identifier" && memberExpression.node.property.name === "glob") {
269
+ const callExpression = memberExpression.parentPath;
296
270
  if (callExpression?.node.type === "CallExpression") {
297
271
  const args = callExpression.get("arguments").map((arg) => arg.evaluate().value);
298
272
  if (args[1]?.eager) {
@@ -913,6 +887,20 @@ function markoPlugin(opts = {}) {
913
887
  name: "marko-vite:pre",
914
888
  enforce: "pre",
915
889
  // Must be pre to allow us to resolve assets before vite.
890
+ sharedDuringBuild: true,
891
+ async buildApp(builder) {
892
+ const { ssr, client } = builder.environments;
893
+ if (!ssr || !client) {
894
+ return;
895
+ }
896
+ if (builder.config?.builder?.buildApp) {
897
+ return;
898
+ }
899
+ if (linked) {
900
+ await builder.build(ssr);
901
+ }
902
+ await builder.build(client);
903
+ },
916
904
  async config(config, env) {
917
905
  let optimize = env.mode === "production";
918
906
  isTest = env.mode === "test";
@@ -963,28 +951,23 @@ function markoPlugin(opts = {}) {
963
951
  if (linked) {
964
952
  baseConfig.markoViteLinked = linked;
965
953
  }
966
- const getCJSInteropBabelConfig = () => ({
967
- ...baseConfig.babelConfig,
968
- plugins: (baseConfig.babelConfig.plugins || []).concat(
969
- plugin({
970
- filter: isBuild || isTest ? void 0 : (path7) => !/^\./.test(path7)
971
- })
972
- )
973
- });
954
+ const cjsInteropMarkoVite = {
955
+ filter: isBuild || isTest ? void 0 : (path7) => !/^\./.test(path7)
956
+ };
974
957
  ssrConfig = {
975
958
  ...baseConfig,
976
959
  output: "html"
977
960
  };
978
961
  ssrCjsConfig = {
979
962
  ...ssrConfig,
980
- babelConfig: getCJSInteropBabelConfig()
963
+ cjsInteropMarkoVite
981
964
  };
982
965
  domConfig = {
983
966
  ...baseConfig,
984
967
  output: "dom"
985
968
  };
986
969
  if (isTest) {
987
- domConfig.babelConfig = getCJSInteropBabelConfig();
970
+ domConfig.cjsInteropMarkoVite = cjsInteropMarkoVite;
988
971
  }
989
972
  hydrateConfig = {
990
973
  ...baseConfig,
@@ -1015,6 +998,7 @@ function markoPlugin(opts = {}) {
1015
998
  if (!registeredTagLib) {
1016
999
  registeredTagLib = true;
1017
1000
  compiler2.taglib.register("@marko/vite", {
1001
+ translate: cjs_interop_translate_default,
1018
1002
  transform: glob_import_transform_default,
1019
1003
  "<head>": { transformer: render_assets_transform_default },
1020
1004
  "<body>": { transformer: render_assets_transform_default },
@@ -1079,6 +1063,10 @@ function markoPlugin(opts = {}) {
1079
1063
  config.build.commonjsOptions ??= {};
1080
1064
  config.build.commonjsOptions.esmExternals = (id) => !isCJSModule(id, rootResolveFile);
1081
1065
  }
1066
+ if (linked && !isSSRBuild) {
1067
+ config.build ??= {};
1068
+ config.build.emptyOutDir = false;
1069
+ }
1082
1070
  if (basePathVar) {
1083
1071
  config.experimental ??= {};
1084
1072
  if (config.experimental.renderBuiltUrl) {
@@ -1123,12 +1111,48 @@ function markoPlugin(opts = {}) {
1123
1111
  }
1124
1112
  };
1125
1113
  },
1114
+ configEnvironment(name, options) {
1115
+ if (name === "ssr") {
1116
+ options.resolve ??= {};
1117
+ const { noExternal } = options.resolve;
1118
+ if (noExternal !== true) {
1119
+ const noExternalReg = /\.marko$/;
1120
+ if (noExternal) {
1121
+ if (Array.isArray(noExternal)) {
1122
+ options.resolve.noExternal = [...noExternal, noExternalReg];
1123
+ } else {
1124
+ options.resolve.noExternal = [noExternal, noExternalReg];
1125
+ }
1126
+ } else {
1127
+ options.resolve.noExternal = noExternalReg;
1128
+ }
1129
+ }
1130
+ options.build ??= {};
1131
+ options.build.emptyOutDir = true;
1132
+ if (!options.build?.rollupOptions?.output) {
1133
+ options.build.rollupOptions ??= {};
1134
+ options.build.rollupOptions.output = {
1135
+ chunkFileNames: `[name]-[hash].js`
1136
+ };
1137
+ }
1138
+ if (!options.build?.commonjsOptions?.esmExternals) {
1139
+ options.build.commonjsOptions ??= {};
1140
+ options.build.commonjsOptions.esmExternals = (id) => !isCJSModule(id, rootResolveFile);
1141
+ }
1142
+ } else {
1143
+ if (linked) {
1144
+ options.build ??= {};
1145
+ options.build.emptyOutDir = false;
1146
+ }
1147
+ }
1148
+ return options;
1149
+ },
1126
1150
  configResolved(config) {
1127
1151
  basePath = config.base;
1128
1152
  cacheDir = config.cacheDir && normalizePath(config.cacheDir);
1129
1153
  getMarkoAssetFns = void 0;
1130
- for (const plugin2 of config.plugins) {
1131
- const fn = plugin2.api?.getMarkoAssetCodeForEntry;
1154
+ for (const plugin of config.plugins) {
1155
+ const fn = plugin.api?.getMarkoAssetCodeForEntry;
1132
1156
  if (fn) {
1133
1157
  if (getMarkoAssetFns) {
1134
1158
  getMarkoAssetFns.push(fn);
@@ -1180,7 +1204,7 @@ function markoPlugin(opts = {}) {
1180
1204
  },
1181
1205
  async options(inputOptions) {
1182
1206
  if (linked && isBuild) {
1183
- if (isSSRBuild) {
1207
+ if (isSSRBuild || this.environment?.name === "ssr") {
1184
1208
  serverManifest = {
1185
1209
  entries: {},
1186
1210
  entrySources: {},
@@ -1212,7 +1236,7 @@ function markoPlugin(opts = {}) {
1212
1236
  }
1213
1237
  },
1214
1238
  async buildStart() {
1215
- if (isBuild && linked && !isSSRBuild) {
1239
+ if (isBuild && linked && !isSSRBuild && this.environment?.name !== "ssr") {
1216
1240
  for (const assetId of serverManifest.ssrAssetIds) {
1217
1241
  this.load({
1218
1242
  id: normalizePath(path6.resolve(root, assetId)),
@@ -1222,6 +1246,9 @@ function markoPlugin(opts = {}) {
1222
1246
  }
1223
1247
  },
1224
1248
  async resolveId(importee, importer, importOpts, ssr = importOpts.ssr) {
1249
+ if (importee === cjsInteropHelpersId) {
1250
+ return cjsInteropHelpersId;
1251
+ }
1225
1252
  if (virtualFiles.has(importee)) {
1226
1253
  return importee;
1227
1254
  }
@@ -1282,6 +1309,9 @@ function markoPlugin(opts = {}) {
1282
1309
  },
1283
1310
  async load(rawId) {
1284
1311
  const id = stripViteQueries(rawId);
1312
+ if (id === cjsInteropHelpersId) {
1313
+ return cjsInteropHelpersCode;
1314
+ }
1285
1315
  if (id === renderAssetsRuntimeId) {
1286
1316
  return renderAssetsRuntimeCode;
1287
1317
  }
@@ -1450,7 +1480,8 @@ if (import.meta.hot) import.meta.hot.accept(() => {});`;
1450
1480
  name: "marko-vite:post",
1451
1481
  apply: "build",
1452
1482
  enforce: "post",
1453
- // We use a "post" plugin to allow us to read the final generated `.html` from vite.
1483
+ // We use a "post" plugin to allow us to read the final generated `.html` from vite.,
1484
+ sharedDuringBuild: true,
1454
1485
  transform(_source, id, opts2) {
1455
1486
  if (!opts2?.ssr && /\.module\.[^.]+(?:\?|$)/.test(id)) {
1456
1487
  return {
@@ -1467,7 +1498,7 @@ if (import.meta.hot) import.meta.hot.accept(() => {});`;
1467
1498
  `Linked builds are currently only supported when in "write" mode.`
1468
1499
  );
1469
1500
  }
1470
- if (isSSRBuild) {
1501
+ if (isSSRBuild || this.environment?.name === "ssr") {
1471
1502
  const dir = outputOptions.dir ? path6.resolve(outputOptions.dir) : path6.resolve(outputOptions.file, "..");
1472
1503
  for (const fileName in bundle) {
1473
1504
  const chunk = bundle[fileName];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marko/vite",
3
- "version": "5.3.8",
3
+ "version": "5.4.0",
4
4
  "description": "A Marko plugin for Vite",
5
5
  "keywords": [
6
6
  "loader",
@@ -1,31 +0,0 @@
1
- import type { PluginObj } from "@babel/core";
2
- /**
3
- * This plugin is designed to transform imports within Marko files to interop between ESM and CJS.
4
- * In Node, ESM files cannot reliably use named imports and default imports from CJS files.
5
- * Additionally, modules which are transpiled from ESM to CJS will use a `__esModule` property to
6
- * signal that the consuming ESM code should treat `exports.default` as the default import.
7
- * This plugin only modifies imports it determined to be for CJS modules
8
- *
9
- * Examples
10
- * 1. Source: ```import { bar as baz } from 'foo';```
11
- * Becomes:```
12
- * import * as _foo from 'foo';
13
- * const { bar: baz } = _foo?.default === void 0 || _foo?.__esModule ? _foo : _foo.default;
14
- * ```
15
- *
16
- * 2. Source: ```import myFoo from 'foo';```
17
- * Becomes: ```
18
- * import * as _myFoo from 'foo';
19
- * const { default: myFoo } = _myFoo?.__esModule ? _myFoo.default : _myFoo;
20
- * ```
21
- *
22
- * 3. Source: ```import foo, * as nsFoo from 'foo';```
23
- * Becomes: ```
24
- * import * as _nsFoo from 'foo';
25
- * const nsFoo = _nsFoo?.default === void 0 || _nsFoo?.__esModule ? _nsFoo : _nsFoo.default
26
- * const { default: myFoo } = _nsFoo?.__esModule ? _nsFoo.default : _nsFoo
27
- * ```
28
- */
29
- export default function plugin(options: {
30
- filter?: (path: string) => boolean;
31
- }): PluginObj;