Skip to content
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

feat: Add CommonJS export for parse5 module #418

Merged
merged 14 commits into from Mar 2, 2022
Merged
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -24,7 +24,9 @@
"typescript": "^4.5.5"
},
"scripts": {
"build": "tsc --build packages/* test",
"build": "npm run build:esm && npm run build:cjs",
"build:esm": "tsc --build packages/* test",
"build:cjs": "tsc -p packages/parse5/tsconfig.cjs.json && echo '{\"type\":\"commonjs\"}' > packages/parse5/dist/cjs/package.json",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this make node think dist/cjs/ is its own package?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will make require('parse5') work in Node versions with ESM support.

Because the files are plain .js files, Node will look at the closest package.json file to determine if the code is ESM or not. We create a package.json for the CJS code, to make sure requiring it works as expected.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i get that part, was just wondering what other effects it might have. since you're telling node the cjs path is its own standalone package by giving it its own package manifest. curiosity more than anything, just wondering what other behaviour it might change in tooling.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of any side-effects, but definitely something worth keeping in mind for future bug-reports. I adopted the pattern from this article from SenseDeep, which is used in several published (but not very popular) modules.

"prettier": "prettier '**/*.{js,ts,md,json,yml}' --loglevel warn",
"format": "npm run format:es && npm run format:prettier",
"format:es": "npm run lint:es -- --fix",
Expand Down
10 changes: 9 additions & 1 deletion packages/parse5/package.json
Expand Up @@ -27,7 +27,15 @@
"serialize"
],
"license": "MIT",
"main": "dist/index.js",
"main": "dist/cjs/index.js",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't we still want the default to be ESM? so the only way to reach any commonjs entrypoints is by reading the package exports

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node versions with ESM support will not read the main property if exports are specified. That means this field is only for non-ESM Node versions, which should use the CJS version.

"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "dist/index.js",
"require": "dist/cjs/index.js"
}
},
Comment on lines +33 to +38
Copy link
Contributor

@milahu milahu Oct 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this breaks rehype/test/parse-error.js in rehypejs/rehype#113

import p5errors from 'parse5/lib/common/error-codes.js'

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/common/error-codes.js' is not defined by "exports" in node_modules/parse5/package.json imported from test/parse-error.js

wontfix in rehype, as ERR is not exported by parse5

→ export as ErrorCodes?

https://nodejs.org/api/esm.html

module files within packages can be accessed by appending a path to the package name unless the package's package.json contains an "exports" field, in which case files within packages can only be accessed via the paths defined in "exports".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the package exports are right IMO. if we have consumers of the error codes enum, we should probably just export it top-level along with ParserError, possibly as a useful name like you said (ErrorCodes).

i.e. in index.ts, export {ERR as ErrorCodes} or something

"repository": {
"type": "git",
"url": "git://github.com/inikulin/parse5.git"
Expand Down
8 changes: 8 additions & 0 deletions packages/parse5/tsconfig.cjs.json
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "CommonJS",
"target": "ES6",
"outDir": "dist/cjs"
}
}