-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prepare for bundling #2087
Prepare for bundling #2087
Conversation
Oxygen deployed a preview of your
Learn more about Hydrogen's GitHub integration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 It seems to be working well with the import/resolve trick, both local and global versions.
I've pushed a few commits to update package-lock and sync some other dependencies. Also left a few comments.
const vitePath = require.resolve('vite', {paths: [root]}); | ||
const viteNodePath = joinPath(vitePath, '..', 'dist', 'node', 'index.js'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes me a bit nervous relying on package internal paths to resolve ESM.
Would it work if we just strip the last part of the path until ..../node_modules/vite
so that import(...)
resolves according to their own package.json? Or maybe that doesn't work?
Eventually we should we start requiring Node 20.6, which already supports import.meta.resolve(...)
.
Alternatively, we could rely on --experimental-import-meta-resolve
flag for lower versions of Node (this returns a promise). We can restart the process to add this flag automatically like we do for --experimental-vm-modules
: https://github.com/Shopify/hydrogen/blob/main/packages/cli/src/hooks/init.ts#L5
There's also a ponyfill but I haven't tried it: https://github.com/wooorm/import-meta-resolve
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the reason I had to do this is that vite has this export config:
"exports": {
".": {
"import": {
"types": "./dist/node/index.d.ts",
"default": "./dist/node/index.js"
},
"require": {
"types": "./index.d.cts",
"default": "./index.cjs"
}
When you use import
it correctly uses the node one. When you use require
it imports the cjs
version.
If you try to import('{path}/node_modules/vite')
it doesn't work:
│ Directory import '/Users/isaac/Projects/hydronext/node_modules/vite' is not │
│ supported resolving ES modules imported from /Users/isaac/src/github.com/Sho │
│ pify/hydrogen/packages/cli/dist/commands/hydrogen/build.js │
│ Did you mean to import │
│ /Users/isaac/Projects/hydronext/node_modules/vite/dist/node/index.js? │
How would this import-meta-resolve help us here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried with
await import.meta.resolve?.('vite', root)
And it resolves it in the current directory and not in root 🤔
Another alternative could be this:
const vitePath = require.resolve('vite', {paths: [root]});
const vitePackageJson = await findUpAndReadPackageJson(vitePath) as {content: {[key: string]: any}, path: string};
const viteNodeIndexFile = vitePackageJson.content.exports?.['.'].import.default
const viteNodePath = joinPath(dirname(vitePackageJson.path), viteNodeIndexFile)
Load the package json and find the correct import there.
We could extract this so it's not repeated in many places and can be called like importViteFrom(root)
or findVitePathFrom(root)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And it resolves it in the current directory and not in root 🤔
So I just learned something: the second parameter is ignored in the Node 20.6 (backproted to 18.19 actually) implementation to be spec compliant.
If you want the second param to work, you need to run with NODE_OPTIONS="--experimental-import-meta-resolve" h2 dev
, which is an experimental feature. In this case we can't use it unless we add this flag automatically as mentioned in my previous comment. Perhaps not worth it for now.
Load the package json and find the correct import there.
I think this one would be safer, yes. The exports field can also be changed (['.'].import.default: string
vs ['.'].import: string
vs ['.'].default: string
) but I guess we can check the common paths for ESM?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this one would be safer, yes. The exports field can also be changed (['.'].import.default: string vs ['.'].import: string vs ['.'].default: string) but I guess we can check the common paths for ESM?
Should we go with this approach? I guess we could have some kind of utility importLocal('...', {esm: true, from: '...'})
or similar that checks exports
if available in the package, or fallback to module
, then main
etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, i'll try to do that :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated all the imports, let me know what you think
'hydrogen:setup:vite': SetupVite, | ||
}; | ||
|
||
export default COMMANDS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the benefit of listing commands manually? Perf?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CLI needs to explicitly import all commands from bundled dependencies, once bundled hydrogen won't act as a "plugin" anymore. The easiest way to do this is to export a list of all commands.
`${outDir}/${GENERATOR_TEMPLATES_DIR}/${GENERATOR_STARTER_DIR}`, | ||
`${outDir}/lib/${GENERATOR_TEMPLATES_DIR}/${GENERATOR_STARTER_DIR}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to move the generated folder from dist/generator-templates
to dist/lib/generator-templates
? Doesn't it work at the root in global CLI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nop, in the bundled CLI everything is at the root so we can't go look for anything at ../
(which is what we were doing for the generator templates here).
In order to look for them at ./
, I had to put them inside lib
, that way the import will work both in development and bundled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see.
There's also a generated dist/virtual-routes
folder created at build time, which is referenced in src/lib/virtual-routes.ts
also with ..
. Do we need to change that one too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed that one, but probably yes, where is that imported? what command do I need to run to test if it works?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only used for the classic remix compiler. Try npm run dev
in examples/classic-remix
. Then the routes /subrequest-profiler
and /graphiql
should be added dynamically from that folder.
The code is in lib/classic-compiler/dev.ts
and lib/virtual-routes.ts
. The actual virtual-routes folder is copied from packages/hydrogen
at build time in packages/cli/tsup.config.ts
.
Co-authored-by: Fran Dios <frankdiox@gmail.com>
import {copy as copyWithFilter, createSymlink} from 'fs-extra/esm'; | ||
import { | ||
inTemporaryDirectory, | ||
copyFile, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated but it would be nice to make filter
available in cli-kit's copyFile
.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Let's try to test this in a new experimental release asap.
* Explicitly export CLI commands * Commit dist folder * Move peerDependencies to dependencies * Improve prettier imports * Some cleanup * Fix prettier import * Import vite with a dynamic path * Fix versions * Fix package.json * install remix * dynamic import for codegen * dynamic import for hydrogen-codegen * dynamic import for mini-oxygen * Build hydrogen * Dynamic import for graphql-config * Dynamic import for remix-run * Remove dist * some cleanup * Update package-lock.json * Update package-lock.json * Apply prettier format * Update some functions * Fix tests * Format * Fix more dynamic imports * Fix more dynamic imports * Some cleanup * format * Upgrade oclif and cli-kit * Update cli version in templates * Update minimum oxygen-cli version to bump oclif/core dep * Dedup package-lock.json * Update packages/cli/package.json Co-authored-by: Fran Dios <frankdiox@gmail.com> * Create import-utils file to extract all custom imports * Extract all local imports to common file * Format code * Update package-lock.json * Remove unnecessary overrides * Clean unused imports * Copy virtual routes inside lib * Fix CLI tests * Fix package-lock * Minor refactor * Changesets --------- Co-authored-by: Fran Dios <fran.dios@shopify.com> Co-authored-by: Fran Dios <frankdiox@gmail.com>
WHY are these changes introduced?
We plan to bundle the hydrogen package into shopify/cli. To do that we need to solve some peerDependencies imports.
WHAT is this pull request doing?
HOW to test your changes?
Post-merge steps
Checklist