-
Notifications
You must be signed in to change notification settings - Fork 3
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
Migrate Levitate to ESM #423
Conversation
import { getListImportsCliArgs, CliError } from './utils/cli'; | ||
import { resolvePackage, resolveTargetPackages } from './utils/npm'; | ||
import { getExportInfo } from './compiler/exports'; | ||
import { getImportsInfo, getGroupedImports } from './compiler/imports.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.
This is the bulk of this PR. changing all these files to import with the .js
extension
export * from './removals'; | ||
export * from './utils'; | ||
export * from './veredict'; | ||
export { printChanges } from './changes.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.
I removed the barrel exports from here. I wanted to do the same in the index file but there are so many exports in that file I'd have to spend a whole day working on that.
@@ -40,11 +41,18 @@ export async function readLevignoreFile(cwdPath: string): Promise<IgnoreExportCh | |||
return {}; | |||
} | |||
|
|||
const levignoreFileContent = require(levignoreFilePath); | |||
const tempFile = path.join(fs.mkdtempSync(path.join(os.tmpdir(), 'levitate')), 'levignore.cjs'); |
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 change is annoying but I can't find a better way to do it. the levignore.js file is a commonjs file but it has a .js
extension. trying to await import(file)
directly will throw a js error, and the import
function doesn't have parameters to tell it it is a commonjs file, it seems to only go based on file extension, thus, I have to copy this in a temporal folder and read it from there.
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 would probably add the gist of the explanation as a comment, so it's easy to remember later why we were doing it like this.
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.
Good idea. I'll 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.
Adding type: module
to package.json instructs node to read all js files as esm. Are you trying to import this file?
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.
@jackw yes. do you know a better alternative?
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.
Would it work if the file you want to import was converted to an es module?
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.
We could, but then we'd break compatibility with projects already using levignore.js in its cjs format.
@@ -187,7 +188,7 @@ export function getPackageJson(packagePath: string): any { | |||
return null; | |||
} | |||
|
|||
return require(getPackageJsonPath(packagePath)); | |||
return readJsonFile(getPackageJsonPath(packagePath)); |
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.
simple change, since require is not defined in esm and we are simply loading a json file. I could had used module.createRequire but this is a simpler solution IMO
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.
Don't we have await import(file, { assert: { type: 'json' } }
support in node 20?
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 want to keep compatibility with node 18 which is still LTS.
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.
LGTM 👍
@@ -40,11 +41,18 @@ export async function readLevignoreFile(cwdPath: string): Promise<IgnoreExportCh | |||
return {}; | |||
} | |||
|
|||
const levignoreFileContent = require(levignoreFilePath); | |||
const tempFile = path.join(fs.mkdtempSync(path.join(os.tmpdir(), 'levitate')), 'levignore.cjs'); |
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 would probably add the gist of the explanation as a comment, so it's easy to remember later why we were doing it like this.
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.
Great work on this @academo ! 🚀
I've left a couple of comments regarding node support and json import.
@@ -40,11 +41,18 @@ export async function readLevignoreFile(cwdPath: string): Promise<IgnoreExportCh | |||
return {}; | |||
} | |||
|
|||
const levignoreFileContent = require(levignoreFilePath); | |||
const tempFile = path.join(fs.mkdtempSync(path.join(os.tmpdir(), 'levitate')), 'levignore.cjs'); |
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.
Adding type: module
to package.json instructs node to read all js files as esm. Are you trying to import this file?
@@ -187,7 +188,7 @@ export function getPackageJson(packagePath: string): any { | |||
return null; | |||
} | |||
|
|||
return require(getPackageJsonPath(packagePath)); | |||
return readJsonFile(getPackageJsonPath(packagePath)); |
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.
Don't we have await import(file, { assert: { type: 'json' } }
support in node 20?
@@ -1,15 +1,25 @@ | |||
{ | |||
"$schema": "http://json.schemastore.org/tsconfig", | |||
"compilerOptions": { | |||
"module": "commonjs", | |||
"moduleResolution": "node", | |||
"module": "node16", |
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.
In the future it would be good to ditch as much of this as we can favour of the base configs.
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 am not a fan of the idea of having a third party determining our configuration and introducing breaking changes at will and breaking our projects
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.
Not sure I agree with that. The breaking change in this example is related to Next. If you want to target node18 why don't we use the recommended node18 tsconfig as we're doing in plugin-tools?
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 rather keep that change out of this PR. I opened an issue here #424 so we can do the change later.
What this PR does / why we need it:
Moves Levitate from commonjs to a ESM library
Relevant changes
Which issue(s) this PR fixes:
Closes #393
Special notes for your reviewer:
Do not get scared by the file count, most of the changes are changing imports to have
.js
extension in them