@shopify/cli-hydrogen 8.1.0 → 8.2.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.
- package/dist/assets/hydrogen/starter/CHANGELOG.md +166 -0
- package/dist/assets/hydrogen/starter/app/components/AddToCartButton.tsx +37 -0
- package/dist/assets/hydrogen/starter/app/components/CartLineItem.tsx +150 -0
- package/dist/assets/hydrogen/starter/app/components/CartMain.tsx +68 -0
- package/dist/assets/hydrogen/starter/app/components/CartSummary.tsx +101 -0
- package/dist/assets/hydrogen/starter/app/components/Header.tsx +3 -3
- package/dist/assets/hydrogen/starter/app/components/PageLayout.tsx +2 -2
- package/dist/assets/hydrogen/starter/app/components/ProductForm.tsx +80 -0
- package/dist/assets/hydrogen/starter/app/components/ProductImage.tsx +23 -0
- package/dist/assets/hydrogen/starter/app/components/ProductPrice.tsx +27 -0
- package/dist/assets/hydrogen/starter/app/lib/session.ts +5 -0
- package/dist/assets/hydrogen/starter/app/root.tsx +23 -36
- package/dist/assets/hydrogen/starter/app/routes/account.$.tsx +1 -5
- package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +12 -70
- package/dist/assets/hydrogen/starter/app/routes/account.orders.$id.tsx +7 -14
- package/dist/assets/hydrogen/starter/app/routes/account.orders._index.tsx +1 -8
- package/dist/assets/hydrogen/starter/app/routes/account.profile.tsx +5 -22
- package/dist/assets/hydrogen/starter/app/routes/account.tsx +0 -1
- package/dist/assets/hydrogen/starter/app/routes/cart.tsx +1 -3
- package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +51 -232
- package/dist/assets/hydrogen/starter/package.json +10 -11
- package/dist/assets/hydrogen/starter/server.ts +4 -0
- package/dist/assets/hydrogen/tailwind/package.json +1 -6
- package/dist/assets/hydrogen/tailwind/tailwind.css +6 -3
- package/dist/assets/hydrogen/vanilla-extract/package.json +2 -3
- package/dist/assets/hydrogen/virtual-routes/components/{Layout.jsx → PageLayout.jsx} +2 -2
- package/dist/assets/hydrogen/virtual-routes/components/RequestDetails.jsx +1 -2
- package/dist/assets/hydrogen/virtual-routes/components/RequestTable.jsx +1 -2
- package/dist/assets/hydrogen/virtual-routes/routes/index.jsx +1 -2
- package/dist/assets/hydrogen/virtual-routes/virtual-root.jsx +8 -30
- package/dist/commands/hydrogen/build.js +33 -10
- package/dist/commands/hydrogen/customer-account/push.js +3 -6
- package/dist/commands/hydrogen/debug/cpu.js +3 -3
- package/dist/commands/hydrogen/deploy.js +14 -3
- package/dist/commands/hydrogen/dev.js +3 -6
- package/dist/commands/hydrogen/env/list.js +1 -2
- package/dist/commands/hydrogen/env/pull.js +2 -4
- package/dist/commands/hydrogen/env/push.js +6 -12
- package/dist/commands/hydrogen/init.d.ts +18 -15
- package/dist/commands/hydrogen/init.js +12 -24
- package/dist/commands/hydrogen/link.js +1 -2
- package/dist/commands/hydrogen/preview.js +4 -6
- package/dist/commands/hydrogen/setup/css.js +29 -12
- package/dist/commands/hydrogen/setup/vite.js +3 -6
- package/dist/commands/hydrogen/setup.js +8 -7
- package/dist/commands/hydrogen/upgrade.js +16 -32
- package/dist/hooks/init.js +50 -6
- package/dist/index.d.ts +46 -46
- package/dist/lib/auth.js +1 -2
- package/dist/lib/build.js +1 -2
- package/dist/lib/bundle/analyzer.js +39 -24
- package/dist/lib/bundle/vite-plugin.js +161 -0
- package/dist/lib/check-cli-version.js +61 -0
- package/dist/lib/check-lockfile.js +2 -2
- package/dist/lib/classic-compiler/build.js +3 -3
- package/dist/lib/classic-compiler/dev.js +5 -10
- package/dist/lib/codegen.js +8 -16
- package/dist/lib/defer.js +2 -4
- package/dist/lib/environment-variables.js +2 -4
- package/dist/lib/file.js +15 -7
- package/dist/lib/flags.js +10 -0
- package/dist/lib/get-oxygen-deployment-data.js +1 -2
- package/dist/lib/graphiql-url.js +1 -2
- package/dist/lib/import-utils.js +3 -2
- package/dist/lib/log.js +11 -22
- package/dist/lib/mini-oxygen/common.js +1 -2
- package/dist/lib/mini-oxygen/node.js +1 -2
- package/dist/lib/missing-routes.js +1 -2
- package/dist/lib/onboarding/common.js +60 -15
- package/dist/lib/onboarding/local.js +14 -13
- package/dist/lib/onboarding/remote.js +16 -9
- package/dist/lib/onboarding/setup-template.mocks.js +6 -3
- package/dist/lib/remix-config.js +2 -4
- package/dist/lib/remix-version-check.js +1 -2
- package/dist/lib/request-events.js +3 -6
- package/dist/lib/setups/css/assets.js +1 -1
- package/dist/lib/setups/css/index.js +17 -10
- package/dist/lib/setups/css/replacers.js +74 -76
- package/dist/lib/setups/css/tailwind.js +16 -20
- package/dist/lib/setups/css/vanilla-extract.js +8 -5
- package/dist/lib/setups/i18n/replacers.js +1 -2
- package/dist/lib/setups/routes/generate.js +18 -19
- package/dist/lib/shell.js +5 -10
- package/dist/lib/template-diff.js +83 -104
- package/dist/lib/template-downloader.js +2 -2
- package/dist/lib/transpile/morph/functions.js +3 -6
- package/dist/lib/transpile/morph/index.js +2 -4
- package/dist/lib/transpile/morph/typedefs.js +3 -6
- package/dist/lib/transpile/morph/utils.js +2 -4
- package/dist/lib/transpile/project.js +4 -3
- package/oclif.manifest.json +51 -4
- package/package.json +8 -12
- package/dist/assets/hydrogen/css-modules/package.json +0 -6
- package/dist/assets/hydrogen/postcss/package.json +0 -10
- package/dist/assets/hydrogen/postcss/postcss.config.js +0 -8
- package/dist/assets/hydrogen/starter/app/components/Cart.tsx +0 -364
- package/dist/assets/hydrogen/tailwind/postcss.config.js +0 -10
- package/dist/assets/hydrogen/tailwind/tailwind.config.js +0 -8
- package/dist/lib/check-version.js +0 -75
- package/dist/lib/setups/css/css-modules.js +0 -23
- package/dist/lib/setups/css/postcss.js +0 -31
package/dist/index.d.ts
CHANGED
|
@@ -90,29 +90,29 @@ declare class Dev extends Command {
|
|
|
90
90
|
worker: {
|
|
91
91
|
type: "option";
|
|
92
92
|
name: string;
|
|
93
|
-
char?: _oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase
|
|
94
|
-
summary?: string
|
|
95
|
-
description?: string
|
|
96
|
-
helpLabel?: string
|
|
97
|
-
helpGroup?: string
|
|
98
|
-
env?: string
|
|
99
|
-
hidden?: boolean
|
|
100
|
-
required?: boolean
|
|
101
|
-
dependsOn?: string[]
|
|
102
|
-
exclusive?: string[]
|
|
103
|
-
exactlyOne?: string[]
|
|
104
|
-
relationships?: _oclif_core_lib_interfaces_parser_js.Relationship[]
|
|
105
|
-
deprecated?: true | _oclif_core_lib_interfaces_parser_js.Deprecation
|
|
106
|
-
aliases?: string[]
|
|
107
|
-
charAliases?: (_oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase)[]
|
|
108
|
-
deprecateAliases?: boolean
|
|
109
|
-
noCacheDefault?: boolean
|
|
110
|
-
helpValue?: string
|
|
111
|
-
options?: readonly string[]
|
|
112
|
-
multiple?: boolean
|
|
113
|
-
multipleNonGreedy?: boolean
|
|
114
|
-
delimiter?: ","
|
|
115
|
-
allowStdin?: boolean | "only"
|
|
93
|
+
char?: _oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase;
|
|
94
|
+
summary?: string;
|
|
95
|
+
description?: string;
|
|
96
|
+
helpLabel?: string;
|
|
97
|
+
helpGroup?: string;
|
|
98
|
+
env?: string;
|
|
99
|
+
hidden?: boolean;
|
|
100
|
+
required?: boolean;
|
|
101
|
+
dependsOn?: string[];
|
|
102
|
+
exclusive?: string[];
|
|
103
|
+
exactlyOne?: string[];
|
|
104
|
+
relationships?: _oclif_core_lib_interfaces_parser_js.Relationship[];
|
|
105
|
+
deprecated?: true | _oclif_core_lib_interfaces_parser_js.Deprecation;
|
|
106
|
+
aliases?: string[];
|
|
107
|
+
charAliases?: (_oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase)[];
|
|
108
|
+
deprecateAliases?: boolean;
|
|
109
|
+
noCacheDefault?: boolean;
|
|
110
|
+
helpValue?: string;
|
|
111
|
+
options?: readonly string[];
|
|
112
|
+
multiple?: boolean;
|
|
113
|
+
multipleNonGreedy?: boolean;
|
|
114
|
+
delimiter?: ",";
|
|
115
|
+
allowStdin?: boolean | "only";
|
|
116
116
|
parse: _oclif_core_lib_interfaces_parser_js.FlagParser<unknown, string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
|
117
117
|
defaultHelp?: unknown;
|
|
118
118
|
input: string[];
|
|
@@ -262,29 +262,29 @@ declare class Preview extends Command {
|
|
|
262
262
|
worker: {
|
|
263
263
|
type: "option";
|
|
264
264
|
name: string;
|
|
265
|
-
char?: _oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase
|
|
266
|
-
summary?: string
|
|
267
|
-
description?: string
|
|
268
|
-
helpLabel?: string
|
|
269
|
-
helpGroup?: string
|
|
270
|
-
env?: string
|
|
271
|
-
hidden?: boolean
|
|
272
|
-
required?: boolean
|
|
273
|
-
dependsOn?: string[]
|
|
274
|
-
exclusive?: string[]
|
|
275
|
-
exactlyOne?: string[]
|
|
276
|
-
relationships?: _oclif_core_lib_interfaces_parser_js.Relationship[]
|
|
277
|
-
deprecated?: true | _oclif_core_lib_interfaces_parser_js.Deprecation
|
|
278
|
-
aliases?: string[]
|
|
279
|
-
charAliases?: (_oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase)[]
|
|
280
|
-
deprecateAliases?: boolean
|
|
281
|
-
noCacheDefault?: boolean
|
|
282
|
-
helpValue?: string
|
|
283
|
-
options?: readonly string[]
|
|
284
|
-
multiple?: boolean
|
|
285
|
-
multipleNonGreedy?: boolean
|
|
286
|
-
delimiter?: ","
|
|
287
|
-
allowStdin?: boolean | "only"
|
|
265
|
+
char?: _oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase;
|
|
266
|
+
summary?: string;
|
|
267
|
+
description?: string;
|
|
268
|
+
helpLabel?: string;
|
|
269
|
+
helpGroup?: string;
|
|
270
|
+
env?: string;
|
|
271
|
+
hidden?: boolean;
|
|
272
|
+
required?: boolean;
|
|
273
|
+
dependsOn?: string[];
|
|
274
|
+
exclusive?: string[];
|
|
275
|
+
exactlyOne?: string[];
|
|
276
|
+
relationships?: _oclif_core_lib_interfaces_parser_js.Relationship[];
|
|
277
|
+
deprecated?: true | _oclif_core_lib_interfaces_parser_js.Deprecation;
|
|
278
|
+
aliases?: string[];
|
|
279
|
+
charAliases?: (_oclif_core_lib_interfaces_alphabet_js.AlphabetLowercase | _oclif_core_lib_interfaces_alphabet_js.AlphabetUppercase)[];
|
|
280
|
+
deprecateAliases?: boolean;
|
|
281
|
+
noCacheDefault?: boolean;
|
|
282
|
+
helpValue?: string;
|
|
283
|
+
options?: readonly string[];
|
|
284
|
+
multiple?: boolean;
|
|
285
|
+
multipleNonGreedy?: boolean;
|
|
286
|
+
delimiter?: ",";
|
|
287
|
+
allowStdin?: boolean | "only";
|
|
288
288
|
parse: _oclif_core_lib_interfaces_parser_js.FlagParser<unknown, string, _oclif_core_lib_interfaces_parser_js.CustomOptions>;
|
|
289
289
|
defaultHelp?: unknown;
|
|
290
290
|
input: string[];
|
package/dist/lib/auth.js
CHANGED
|
@@ -21,8 +21,7 @@ async function login(root, shop) {
|
|
|
21
21
|
if (typeof shop !== "string") {
|
|
22
22
|
shop = existingConfig.shop;
|
|
23
23
|
}
|
|
24
|
-
if (shop)
|
|
25
|
-
shop = await normalizeStoreFqdn(shop);
|
|
24
|
+
if (shop) shop = await normalizeStoreFqdn(shop);
|
|
26
25
|
const hideLoginInfo = showLoginInfo();
|
|
27
26
|
if (!shop || !shopName || !email || forcePrompt || shop !== existingConfig.shop) {
|
|
28
27
|
const token = await ensureAuthenticatedBusinessPlatform().catch(() => {
|
package/dist/lib/build.js
CHANGED
|
@@ -43,8 +43,7 @@ async function getTemplateAppFile(filepath, root) {
|
|
|
43
43
|
return url.protocol === "file:" ? fileURLToPath(url) : url.toString();
|
|
44
44
|
}
|
|
45
45
|
function getStarterDir(useSource = !!process.env.SHOPIFY_UNIT_TEST) {
|
|
46
|
-
if (useSource)
|
|
47
|
-
return getSkeletonSourceDir();
|
|
46
|
+
if (useSource) return getSkeletonSourceDir();
|
|
48
47
|
return getAssetsDir(ASSETS_STARTER_DIR);
|
|
49
48
|
}
|
|
50
49
|
function getSkeletonSourceDir() {
|
|
@@ -4,24 +4,25 @@ import colors from '@shopify/cli-kit/node/colors';
|
|
|
4
4
|
import { renderWarning } from '@shopify/cli-kit/node/ui';
|
|
5
5
|
import { getAssetsDir } from '../build.js';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const BUNDLE_ANALYZER_JSON_FILE = "metafile.server.json";
|
|
8
|
+
const BUNDLE_ANALYZER_HTML_FILE = "server-bundle-analyzer.html";
|
|
9
|
+
async function classicBuildBundleAnalysis(buildPath) {
|
|
8
10
|
const workerBuildPath = joinPath(buildPath, "worker");
|
|
9
|
-
const serverMetafile =
|
|
11
|
+
const serverMetafile = BUNDLE_ANALYZER_JSON_FILE;
|
|
10
12
|
const clientMetafile = "metafile.js.json";
|
|
11
13
|
const hasMetafile = (await Promise.all([
|
|
12
14
|
fileExists(joinPath(workerBuildPath, serverMetafile)),
|
|
13
15
|
fileExists(joinPath(workerBuildPath, clientMetafile))
|
|
14
16
|
])).every(Boolean);
|
|
15
|
-
if (!hasMetafile)
|
|
16
|
-
return null;
|
|
17
|
+
if (!hasMetafile) return null;
|
|
17
18
|
try {
|
|
18
19
|
await Promise.all([
|
|
19
|
-
|
|
20
|
+
classicWriteBundleAnalyzerFile(
|
|
20
21
|
workerBuildPath,
|
|
21
22
|
serverMetafile,
|
|
22
23
|
"worker-bundle-analyzer.html"
|
|
23
24
|
),
|
|
24
|
-
|
|
25
|
+
classicWriteBundleAnalyzerFile(
|
|
25
26
|
workerBuildPath,
|
|
26
27
|
clientMetafile,
|
|
27
28
|
"client-bundle-analyzer.html"
|
|
@@ -37,34 +38,48 @@ async function buildBundleAnalysis(buildPath) {
|
|
|
37
38
|
return null;
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
|
-
async function
|
|
41
|
+
async function getAnalyzerTemplate() {
|
|
42
|
+
return readFile(await getAssetsDir("bundle", "analyzer.html"));
|
|
43
|
+
}
|
|
44
|
+
function injectAnalyzerTemplateData(analysisTemplate, metafile) {
|
|
45
|
+
return analysisTemplate.replace(
|
|
46
|
+
`globalThis.METAFILE = '';`,
|
|
47
|
+
`globalThis.METAFILE = '${Buffer.from(metafile, "utf-8").toString(
|
|
48
|
+
"base64"
|
|
49
|
+
)}';`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
async function classicWriteBundleAnalyzerFile(workerBuildPath, metafileName, outputFile) {
|
|
41
53
|
const metafile = await readFile(joinPath(workerBuildPath, metafileName), {
|
|
42
54
|
encoding: "utf8"
|
|
43
55
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
await
|
|
56
|
+
await writeFile(
|
|
57
|
+
joinPath(workerBuildPath, outputFile),
|
|
58
|
+
injectAnalyzerTemplateData(await getAnalyzerTemplate(), metafile)
|
|
47
59
|
);
|
|
48
|
-
const templateWithMetafile = analysisTemplate.replace(
|
|
49
|
-
`globalThis.METAFILE = '';`,
|
|
50
|
-
`globalThis.METAFILE = '${metafile64}';`
|
|
51
|
-
);
|
|
52
|
-
await writeFile(joinPath(workerBuildPath, outputFile), templateWithMetafile);
|
|
53
60
|
}
|
|
54
|
-
async function getBundleAnalysisSummary(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
async function getBundleAnalysisSummary(distPath) {
|
|
62
|
+
try {
|
|
63
|
+
const esbuild = await import('esbuild');
|
|
64
|
+
const metafileAnalysis = await esbuild.analyzeMetafile(
|
|
65
|
+
await readFile(joinPath(distPath, BUNDLE_ANALYZER_JSON_FILE)),
|
|
66
|
+
{ color: true }
|
|
67
|
+
);
|
|
68
|
+
return " \u2502\n " + metafileAnalysis.split("\n").filter((line) => {
|
|
62
69
|
const match = line.match(
|
|
63
70
|
/(.*)(node_modules\/|server-assets-manifest:|server-entry-module:)(react-dom|@remix-run|@shopify\/hydrogen|react-router|react-router-dom)\/(.*)/g
|
|
64
71
|
);
|
|
65
72
|
return !match;
|
|
66
73
|
}).slice(2, 12).join("\n").replace(/dist\/worker\/_assets\/.*$/ms, "\n").replace(/\n/g, "\n ").replace(/(\.\.\/)+node_modules\//g, (match) => colors.dim(match));
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.warn(
|
|
76
|
+
"Could not generate bundle analysis summary:",
|
|
77
|
+
error.message
|
|
78
|
+
);
|
|
67
79
|
}
|
|
68
80
|
}
|
|
81
|
+
function classicGetBundleAnalysisSummary(bundlePath) {
|
|
82
|
+
return getBundleAnalysisSummary(dirname(bundlePath));
|
|
83
|
+
}
|
|
69
84
|
|
|
70
|
-
export {
|
|
85
|
+
export { BUNDLE_ANALYZER_HTML_FILE, BUNDLE_ANALYZER_JSON_FILE, classicBuildBundleAnalysis, classicGetBundleAnalysisSummary, getAnalyzerTemplate, getBundleAnalysisSummary, injectAnalyzerTemplateData };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { relativePath, joinPath } from '@shopify/cli-kit/node/path';
|
|
2
|
+
import { getAnalyzerTemplate, BUNDLE_ANALYZER_JSON_FILE, BUNDLE_ANALYZER_HTML_FILE, injectAnalyzerTemplateData } from './analyzer.js';
|
|
3
|
+
|
|
4
|
+
function hydrogenBundleAnalyzer(pluginOptions) {
|
|
5
|
+
let config;
|
|
6
|
+
return {
|
|
7
|
+
name: "hydrogen:bundle-analyzer",
|
|
8
|
+
configResolved(_config) {
|
|
9
|
+
config = _config;
|
|
10
|
+
},
|
|
11
|
+
async generateBundle(options, bundle) {
|
|
12
|
+
if (!config.build.ssr) return;
|
|
13
|
+
const { root } = config;
|
|
14
|
+
const workerFile = Object.values(bundle).find(
|
|
15
|
+
(chunk) => chunk.type === "chunk"
|
|
16
|
+
);
|
|
17
|
+
if (!workerFile || workerFile.type !== "chunk" || !workerFile.facadeModuleId || !options.dir) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const analysisTemplate = await getAnalyzerTemplate().catch(() => null);
|
|
21
|
+
if (!analysisTemplate) {
|
|
22
|
+
console.warn("Bundle analyzer template not found");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const allModIds = new Set(Object.keys(workerFile.modules));
|
|
26
|
+
const modsToAnalyze = [];
|
|
27
|
+
for (const modId of allModIds) {
|
|
28
|
+
if (isViteCjsHelper(modId) || isViteTransformHelper(modId)) continue;
|
|
29
|
+
const mod = this.getModuleInfo(modId);
|
|
30
|
+
if (!mod?.id) continue;
|
|
31
|
+
modsToAnalyze.push(mod);
|
|
32
|
+
for (const importedId of [
|
|
33
|
+
...mod.importedIds,
|
|
34
|
+
...mod.dynamicallyImportedIds
|
|
35
|
+
]) {
|
|
36
|
+
if (!isViteCjsHelper(importedId) && !isViteTransformHelper(importedId)) {
|
|
37
|
+
allModIds.add(importedId);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const modsMeta = /* @__PURE__ */ new Map();
|
|
42
|
+
const renderedSizes = /* @__PURE__ */ new Map();
|
|
43
|
+
const resultError = await Promise.all(
|
|
44
|
+
modsToAnalyze.map(async (mod) => {
|
|
45
|
+
const relativeModId = relativePath(root, mod.id);
|
|
46
|
+
const modBundleInfo = workerFile.modules[mod.id];
|
|
47
|
+
const originalCodeBytes = modBundleInfo?.originalLength ?? mod.code?.length ?? 0;
|
|
48
|
+
let resultingCodeBytes = modBundleInfo?.renderedLength ?? 0;
|
|
49
|
+
if (pluginOptions?.minify && modBundleInfo?.code) {
|
|
50
|
+
const minifiedCode = await pluginOptions.minify(modBundleInfo.code, mod.id).catch(() => null);
|
|
51
|
+
if (minifiedCode) resultingCodeBytes = minifiedCode.length;
|
|
52
|
+
}
|
|
53
|
+
renderedSizes.set(relativeModId, resultingCodeBytes);
|
|
54
|
+
const resolveImportString = (importString) => this.resolve(importString, mod.id);
|
|
55
|
+
let isESM = !mod.code || /(^\s*export\s+[\w\{]|^\s*import\s+[\w\{'"]|\bimport\()|\bcreateRequire\(/ms.test(
|
|
56
|
+
mod.code
|
|
57
|
+
) || !/((^|\b)exports\b|\brequire\()/.test(mod.code);
|
|
58
|
+
const staticImportsMeta = createImportsMeta(
|
|
59
|
+
mod.importedIds,
|
|
60
|
+
"import-statement",
|
|
61
|
+
root,
|
|
62
|
+
resolveImportString,
|
|
63
|
+
mod.code
|
|
64
|
+
);
|
|
65
|
+
const dynamicImportsMeta = createImportsMeta(
|
|
66
|
+
mod.dynamicallyImportedIds,
|
|
67
|
+
"dynamic-import",
|
|
68
|
+
root,
|
|
69
|
+
resolveImportString,
|
|
70
|
+
mod.code
|
|
71
|
+
);
|
|
72
|
+
const importsMeta = (await Promise.all([...staticImportsMeta, ...dynamicImportsMeta])).reduce((acc, { importedId, ...meta }) => {
|
|
73
|
+
if (isViteCjsHelper(importedId)) {
|
|
74
|
+
isESM = false;
|
|
75
|
+
} else if (!isViteTransformHelper(importedId)) {
|
|
76
|
+
acc.push(meta);
|
|
77
|
+
}
|
|
78
|
+
return acc;
|
|
79
|
+
}, []);
|
|
80
|
+
modsMeta.set(relativeModId, {
|
|
81
|
+
bytes: originalCodeBytes,
|
|
82
|
+
format: isESM ? "esm" : "cjs",
|
|
83
|
+
imports: importsMeta
|
|
84
|
+
});
|
|
85
|
+
})
|
|
86
|
+
).then(() => null).catch((error) => error);
|
|
87
|
+
if (resultError) {
|
|
88
|
+
console.warn(
|
|
89
|
+
"Bundle analyzer failed to analyze the bundle:",
|
|
90
|
+
resultError
|
|
91
|
+
);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const inputs = Object.fromEntries(modsMeta.entries());
|
|
95
|
+
const metafile = {
|
|
96
|
+
inputs,
|
|
97
|
+
outputs: {
|
|
98
|
+
[relativePath(root, joinPath(options.dir, workerFile.fileName))]: {
|
|
99
|
+
imports: workerFile.imports,
|
|
100
|
+
exports: workerFile.exports,
|
|
101
|
+
entryPoint: relativePath(root, workerFile.facadeModuleId),
|
|
102
|
+
bytes: workerFile.code.length ?? 0,
|
|
103
|
+
inputs: Object.entries(inputs).reduce((acc, [key, item]) => {
|
|
104
|
+
acc[key] = {
|
|
105
|
+
bytesInOutput: renderedSizes.get(key) ?? item.bytes ?? 0
|
|
106
|
+
};
|
|
107
|
+
return acc;
|
|
108
|
+
}, {})
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
bundle[BUNDLE_ANALYZER_JSON_FILE] = {
|
|
113
|
+
type: "asset",
|
|
114
|
+
fileName: BUNDLE_ANALYZER_JSON_FILE,
|
|
115
|
+
name: BUNDLE_ANALYZER_JSON_FILE,
|
|
116
|
+
needsCodeReference: false,
|
|
117
|
+
source: JSON.stringify(metafile, null, 2)
|
|
118
|
+
};
|
|
119
|
+
bundle[BUNDLE_ANALYZER_HTML_FILE] = {
|
|
120
|
+
type: "asset",
|
|
121
|
+
fileName: BUNDLE_ANALYZER_HTML_FILE,
|
|
122
|
+
name: BUNDLE_ANALYZER_HTML_FILE,
|
|
123
|
+
needsCodeReference: false,
|
|
124
|
+
source: injectAnalyzerTemplateData(
|
|
125
|
+
analysisTemplate,
|
|
126
|
+
JSON.stringify(metafile)
|
|
127
|
+
)
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function isViteCjsHelper(id) {
|
|
133
|
+
return /(commonjsHelpers\.js$|\?commonjs\-)/.test(id);
|
|
134
|
+
}
|
|
135
|
+
function isViteTransformHelper(id) {
|
|
136
|
+
return id.endsWith("?transform-only");
|
|
137
|
+
}
|
|
138
|
+
async function findOriginalImportName(filepath, importerCode, resolve) {
|
|
139
|
+
const matches = importerCode.matchAll(/import\s[^'"]*?['"]([^'"]+)['"]/g) ?? [];
|
|
140
|
+
for (const [, match] of matches) {
|
|
141
|
+
if (match) {
|
|
142
|
+
const resolvedMod = await resolve(match);
|
|
143
|
+
if (resolvedMod?.id === filepath) {
|
|
144
|
+
return match;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return filepath;
|
|
149
|
+
}
|
|
150
|
+
function createImportsMeta(ids, kind, root, resolveImportString, code) {
|
|
151
|
+
return ids.map(async (importedId) => {
|
|
152
|
+
return {
|
|
153
|
+
importedId,
|
|
154
|
+
path: relativePath(root, importedId),
|
|
155
|
+
kind,
|
|
156
|
+
original: code ? await findOriginalImportName(importedId, code, resolveImportString) : importedId
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export { hydrogenBundleAnalyzer };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { findUpAndReadPackageJson, checkForNewVersion, packageManagerFromUserAgent } from '@shopify/cli-kit/node/node-package-manager';
|
|
3
|
+
import { renderInfo } from '@shopify/cli-kit/node/ui';
|
|
4
|
+
import { isHydrogenMonorepo } from './build.js';
|
|
5
|
+
import { inferPackageManagerForGlobalCLI } from '@shopify/cli-kit/node/is-global';
|
|
6
|
+
|
|
7
|
+
const UPGRADABLE_CLI_NAMES = {
|
|
8
|
+
cli: "@shopify/cli",
|
|
9
|
+
cliHydrogen: "@shopify/cli-hydrogen",
|
|
10
|
+
createApp: "@shopify/create-hydrogen"
|
|
11
|
+
};
|
|
12
|
+
async function checkCurrentCLIVersion() {
|
|
13
|
+
if (isHydrogenMonorepo && !process.env.SHOPIFY_UNIT_TEST) return;
|
|
14
|
+
const { content: pkgJson } = await findUpAndReadPackageJson(
|
|
15
|
+
fileURLToPath(import.meta.url)
|
|
16
|
+
).catch(() => ({ content: void 0 }));
|
|
17
|
+
const pkgName = pkgJson?.name;
|
|
18
|
+
const currentVersion = pkgJson?.version;
|
|
19
|
+
if (!pkgName || !currentVersion || !Object.values(UPGRADABLE_CLI_NAMES).some((name) => name === pkgName) || currentVersion.includes("next") || currentVersion.includes("experimental") || currentVersion.includes("snapshot")) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const newVersionAvailable = await checkForNewVersion(pkgName, currentVersion);
|
|
23
|
+
if (!newVersionAvailable) return;
|
|
24
|
+
const reference = [
|
|
25
|
+
{
|
|
26
|
+
link: {
|
|
27
|
+
label: "Hydrogen releases",
|
|
28
|
+
url: "https://github.com/Shopify/hydrogen/releases"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
if (pkgName === UPGRADABLE_CLI_NAMES.cli) {
|
|
33
|
+
reference.push({
|
|
34
|
+
link: {
|
|
35
|
+
label: "Global CLI reference",
|
|
36
|
+
url: "https://shopify.dev/docs/api/shopify-cli/"
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return (packageManager) => {
|
|
41
|
+
packageManager ??= packageManagerFromUserAgent();
|
|
42
|
+
if (packageManager === "unknown" || !packageManager) {
|
|
43
|
+
packageManager = inferPackageManagerForGlobalCLI();
|
|
44
|
+
}
|
|
45
|
+
if (packageManager === "unknown") {
|
|
46
|
+
packageManager = "npm";
|
|
47
|
+
}
|
|
48
|
+
const installMessage = pkgName === UPGRADABLE_CLI_NAMES.cli ? `Please install the latest Shopify CLI version with \`${packageManager === "yarn" ? `yarn global add ${UPGRADABLE_CLI_NAMES.cli}` : `${packageManager} install -g ${UPGRADABLE_CLI_NAMES.cli}`}\` and try again.` : `Please use the latest version with \`${packageManager} create @shopify/hydrogen@latest\``;
|
|
49
|
+
renderInfo({
|
|
50
|
+
headline: "Upgrade available",
|
|
51
|
+
body: `Version ${newVersionAvailable} of ${pkgName} is now available.
|
|
52
|
+
You are currently running v${currentVersion}.
|
|
53
|
+
|
|
54
|
+
` + installMessage,
|
|
55
|
+
reference
|
|
56
|
+
});
|
|
57
|
+
return { currentVersion, newVersion: newVersionAvailable };
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { UPGRADABLE_CLI_NAMES, checkCurrentCLIVersion };
|
|
@@ -4,6 +4,7 @@ import { checkIfIgnoredInGitRepository } from '@shopify/cli-kit/node/git';
|
|
|
4
4
|
import { renderWarning } from '@shopify/cli-kit/node/ui';
|
|
5
5
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
6
6
|
import { packageManagers } from './package-managers.js';
|
|
7
|
+
import { isHydrogenMonorepo } from './build.js';
|
|
7
8
|
|
|
8
9
|
function missingLockfileWarning(shouldExit) {
|
|
9
10
|
const headline = "No lockfile found";
|
|
@@ -53,8 +54,7 @@ function lockfileIgnoredWarning(lockfile) {
|
|
|
53
54
|
renderWarning({ headline, body, nextSteps });
|
|
54
55
|
}
|
|
55
56
|
async function checkLockfileStatus(directory, shouldExit = false) {
|
|
56
|
-
if (process.env.
|
|
57
|
-
return;
|
|
57
|
+
if (isHydrogenMonorepo && !process.env.SHOPIFY_UNIT_TEST) return;
|
|
58
58
|
const foundPackageManagers = [];
|
|
59
59
|
for (const packageManager of packageManagers) {
|
|
60
60
|
if (await fileExists(resolvePath(directory, packageManager.lockfile))) {
|
|
@@ -8,7 +8,7 @@ import { checkLockfileStatus } from '../check-lockfile.js';
|
|
|
8
8
|
import { findMissingRoutes } from '../missing-routes.js';
|
|
9
9
|
import { muteRemixLogs, createRemixLogger } from '../log.js';
|
|
10
10
|
import { codegen } from '../codegen.js';
|
|
11
|
-
import {
|
|
11
|
+
import { classicBuildBundleAnalysis, classicGetBundleAnalysisSummary } from '../bundle/analyzer.js';
|
|
12
12
|
import { isCI } from '../is-ci.js';
|
|
13
13
|
import { importLocal } from '../import-utils.js';
|
|
14
14
|
|
|
@@ -76,7 +76,7 @@ async function runClassicCompilerBuild({
|
|
|
76
76
|
]);
|
|
77
77
|
if (process.env.NODE_ENV !== "development") {
|
|
78
78
|
console.timeEnd(LOG_WORKER_BUILT);
|
|
79
|
-
const bundleAnalysisPath = await
|
|
79
|
+
const bundleAnalysisPath = await classicBuildBundleAnalysis(buildPath);
|
|
80
80
|
const sizeMB = await fileSize(buildPathWorkerFile) / (1024 * 1024);
|
|
81
81
|
const formattedSize = colors.yellow(sizeMB.toFixed(2) + " MB");
|
|
82
82
|
outputInfo(
|
|
@@ -86,7 +86,7 @@ async function runClassicCompilerBuild({
|
|
|
86
86
|
);
|
|
87
87
|
if (bundleStats && bundleAnalysisPath) {
|
|
88
88
|
outputInfo(
|
|
89
|
-
outputContent`${await
|
|
89
|
+
outputContent`${await classicGetBundleAnalysisSummary(buildPathWorkerFile) || "\n"}\n │\n └─── ${outputToken.link(
|
|
90
90
|
"Complete analysis: " + bundleAnalysisPath,
|
|
91
91
|
bundleAnalysisPath
|
|
92
92
|
)}\n\n`
|
|
@@ -39,12 +39,9 @@ async function runClassicCompilerDev({
|
|
|
39
39
|
cliConfig,
|
|
40
40
|
verbose
|
|
41
41
|
}) {
|
|
42
|
-
if (!process.env.NODE_ENV)
|
|
43
|
-
|
|
44
|
-
if (
|
|
45
|
-
setH2OVerbose();
|
|
46
|
-
if (!isH2Verbose())
|
|
47
|
-
muteDevLogs();
|
|
42
|
+
if (!process.env.NODE_ENV) process.env.NODE_ENV = "development";
|
|
43
|
+
if (verbose) setH2OVerbose();
|
|
44
|
+
if (!isH2Verbose()) muteDevLogs();
|
|
48
45
|
const { root, publicPath, buildPathClient, buildPathWorkerFile } = getProjectPaths(appPath);
|
|
49
46
|
const copyFilesPromise = copyPublicFiles(publicPath, buildPathClient);
|
|
50
47
|
const cliCommandPromise = getCliCommand(root);
|
|
@@ -111,8 +108,7 @@ async function runClassicCompilerDev({
|
|
|
111
108
|
let miniOxygen;
|
|
112
109
|
let codegenProcess;
|
|
113
110
|
async function safeStartMiniOxygen() {
|
|
114
|
-
if (miniOxygen)
|
|
115
|
-
return;
|
|
111
|
+
if (miniOxygen) return;
|
|
116
112
|
const { allVariables, logInjectedVariables } = await envPromise;
|
|
117
113
|
miniOxygen = await startMiniOxygen(
|
|
118
114
|
{
|
|
@@ -183,8 +179,7 @@ async function runClassicCompilerDev({
|
|
|
183
179
|
} else if (!skipRebuildLogs) {
|
|
184
180
|
skipRebuildLogs = false;
|
|
185
181
|
console.timeEnd(LOG_REBUILT);
|
|
186
|
-
if (!miniOxygen)
|
|
187
|
-
console.log("");
|
|
182
|
+
if (!miniOxygen) console.log("");
|
|
188
183
|
}
|
|
189
184
|
if (!miniOxygen && !await serverBundleExists()) {
|
|
190
185
|
return renderFatalError({
|
package/dist/lib/codegen.js
CHANGED
|
@@ -22,8 +22,7 @@ function normalizeCodegenError(errorMessage, rootDirectory) {
|
|
|
22
22
|
const parsedError = errorMessage.split("AbortError: ")[1] ?? "";
|
|
23
23
|
const message2 = parsedError.split("\n")[0];
|
|
24
24
|
const details2 = parsedError.match(/tryMessage: '(.*)',$/m)?.[1];
|
|
25
|
-
if (message2)
|
|
26
|
-
return { message: message2, details: details2 };
|
|
25
|
+
if (message2) return { message: message2, details: details2 };
|
|
27
26
|
}
|
|
28
27
|
const [first = "", ...rest] = errorMessage.replaceAll("[FAILED]", "").replace(/\s{2,}/g, "\n").replace(/\n,\n/, "\n").trim().split("\n");
|
|
29
28
|
const message = "[Codegen] " + first;
|
|
@@ -66,15 +65,11 @@ function spawnCodegenProcess({
|
|
|
66
65
|
const child = spawn(command, args, { stdio: ["inherit", "ignore", "pipe"] });
|
|
67
66
|
child.stderr.on("data", (data) => {
|
|
68
67
|
const dataString = typeof data === "string" ? data : data?.toString?.("utf8") ?? "";
|
|
69
|
-
if (!dataString)
|
|
70
|
-
return;
|
|
68
|
+
if (!dataString) return;
|
|
71
69
|
const { message, details } = normalizeCodegenError(dataString, rootDirectory);
|
|
72
|
-
if (/`punycode`/.test(message))
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
return;
|
|
76
|
-
if (/console\.time(End)?\(\)/.test(message))
|
|
77
|
-
return;
|
|
70
|
+
if (/`punycode`/.test(message)) return;
|
|
71
|
+
if (/\.body\[\d\]/.test(message)) return;
|
|
72
|
+
if (/console\.time(End)?\(\)/.test(message)) return;
|
|
78
73
|
console.log("");
|
|
79
74
|
renderWarning({ headline: message, body: details });
|
|
80
75
|
});
|
|
@@ -90,8 +85,7 @@ function spawnCodegenProcess({
|
|
|
90
85
|
}
|
|
91
86
|
function codegen(options) {
|
|
92
87
|
return generateTypes(options).catch((error) => {
|
|
93
|
-
if (error instanceof AbortError)
|
|
94
|
-
throw error;
|
|
88
|
+
if (error instanceof AbortError) throw error;
|
|
95
89
|
const { message, details } = normalizeCodegenError(
|
|
96
90
|
error.message,
|
|
97
91
|
options.rootDirectory
|
|
@@ -117,8 +111,7 @@ async function generateTypes({
|
|
|
117
111
|
const { config: codegenConfig } = (
|
|
118
112
|
// Load <root>/codegen.ts if available
|
|
119
113
|
await loadCodegenConfig({
|
|
120
|
-
configFilePath
|
|
121
|
-
searchPlaces: [dirs.rootDirectory]
|
|
114
|
+
configFilePath: configFilePath ?? dirs.rootDirectory
|
|
122
115
|
}) || // Fall back to default config
|
|
123
116
|
await generateDefaultConfig(dirs, forceSfapiVersion)
|
|
124
117
|
);
|
|
@@ -223,8 +216,7 @@ async function generateDefaultConfig({
|
|
|
223
216
|
};
|
|
224
217
|
}
|
|
225
218
|
function findGqlProject(schemaFilepath, gqlConfig) {
|
|
226
|
-
if (!gqlConfig)
|
|
227
|
-
return;
|
|
219
|
+
if (!gqlConfig) return;
|
|
228
220
|
const schemaFilename = basename(schemaFilepath);
|
|
229
221
|
return Object.values(gqlConfig.projects || {}).find(
|
|
230
222
|
(project) => typeof project.schema === "string" && project.schema.endsWith(schemaFilename)
|
package/dist/lib/defer.js
CHANGED
|
@@ -2,13 +2,11 @@ function deferPromise() {
|
|
|
2
2
|
const deferred = { state: "pending" };
|
|
3
3
|
deferred.promise = new Promise((resolve, reject) => {
|
|
4
4
|
deferred.resolve = (value) => {
|
|
5
|
-
if (deferred.state === "pending")
|
|
6
|
-
deferred.state = "resolved";
|
|
5
|
+
if (deferred.state === "pending") deferred.state = "resolved";
|
|
7
6
|
return resolve(value);
|
|
8
7
|
};
|
|
9
8
|
deferred.reject = (reason) => {
|
|
10
|
-
if (deferred.state === "pending")
|
|
11
|
-
deferred.state = "rejected";
|
|
9
|
+
if (deferred.state === "pending") deferred.state = "rejected";
|
|
12
10
|
return reject(reason);
|
|
13
11
|
};
|
|
14
12
|
});
|
|
@@ -76,10 +76,8 @@ async function getRemoteVariables(root, envHandle, envBranch) {
|
|
|
76
76
|
const remoteVariables = {};
|
|
77
77
|
const remoteSecrets = {};
|
|
78
78
|
for (const { key, value, isSecret } of envVariables) {
|
|
79
|
-
if (isSecret)
|
|
80
|
-
|
|
81
|
-
else
|
|
82
|
-
remoteVariables[key] = value;
|
|
79
|
+
if (isSecret) remoteSecrets[key] = value;
|
|
80
|
+
else remoteVariables[key] = value;
|
|
83
81
|
}
|
|
84
82
|
return { remoteVariables, remoteSecrets };
|
|
85
83
|
}
|