-
Notifications
You must be signed in to change notification settings - Fork 470
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(sdk): Build @dotcms/client
in commonjs and esmodule
#29699
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
nicobytes
approved these changes
Aug 22, 2024
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.
Wow, great research on this, and yes, library publishing is a complex topic!
valentinogiardino
approved these changes
Aug 22, 2024
zJaaal
approved these changes
Aug 22, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What happen?
TLDR: The library was not working with some frameworks, example: Astro, Nodejs or Nextra (and probably others) because they wanted commonjs and didn't have that.
What did I do?
I transform our library into a “dual-package” library, that supports both CommonJS and ES Modules.
Is 2024 why do we need this?
Under certain conditions, Astro, Nextra, Nodejs and probaly others require CommonJS.
What conditions?
Imagine your library
package.json
looks like this:For this, Astro will look for the
main
field and useindex.cjs.js
as the entry point in the server.But in the browser, Astro will look for the
module
field and useindex.esm.js
as the entry point.Now we add
"type": "module"
to thepackage.json
:Astro fails to build:
And this is because both files are
.js
and Astro (well node resolution strategy) will try to load the.js
file as an ES module but themain
is the commonjs one.So it doesn't matter if we have
"module": "./index.esm.js"
it will go to the"main": "./index.cjs.js"
.If instead the
package.json
looked like this:It would work because the file extensions are
.cjs
and.mjs
. You will see more of this in the Node module resolution strategy.Another apporach to make it works is if we use
exports
because we can specify the entry point forimport
andrequire
:This will work too because we are specifying the entry point for
import
(esmodule) andrequire
(commonjs).Node module resolution strategy
Strategy that determines how Node.js finds and loads modules.
First node look for modules in the following order:
'./'
or'../'
)node_modules
directories (starting from the current directory and moving up)File extensions:
.js
,.cjs.js
,.mjs.js
node think it can be CommonJS or ES module, only care the real extension..cjs
node think it is CommonJS.mjs
node think it is ES moduletype
property in thepackage.json
:"type": "module"
: Node think all.js
files are ES modules.type
is provided node thinks all.js
files are CommonJS."exports"
in thepackage.json
:"main"
and"module"
fields.Dual package are @#$#$% hard
My proposal is to provide a dual package that works with all the frameworks. In order to do this I leverage the
exports
property.So
@dotcms/client
package.json
used to look like this:And now it looks like this:
And this is pretty much it, hope you find it useful.
FAQs: Understanding the JavaScript Ecosystem and Module Systems
1. What is a JavaScript Module?
A JavaScript module is a reusable piece of code that you can import into other JavaScript files. Modules help keep code organized and maintainable by breaking it into smaller, manageable parts. There are two main module formats in JavaScript:
require
.import
andexport
syntax. This is increasingly used in modern JavaScript environments, especially in browsers.2. What is Astro?
Astro is a modern web framework designed for building fast, content-focused websites. It allows developers to use components from different frameworks (like React, Vue, etc.) while focusing on delivering optimized, static sites. Astro automatically determines the most efficient way to render pages, which sometimes requires CommonJS modules.
3. Why do we need CommonJS (CJS) in 2024?
Even though ES Modules are the future of JavaScript, some frameworks (like Astro, Node.js, and others) still require CommonJS under certain conditions, especially on the server-side. This is because Node.js has long supported CommonJS, and many tools and libraries still rely on it.
4. What is a "dual-package" library?
A dual-package library is a package that supports both CommonJS (CJS) and ES Modules (ESM). This allows the same library to work across different environments, such as older Node.js versions (which may need CJS) and modern JavaScript environments (which prefer ESM).
5. Why do we need a "dual-package" library?
To ensure compatibility across various frameworks and environments. Some tools expect CJS modules, while others expect ESM modules. A dual-package library can satisfy both requirements, preventing compatibility issues during builds or runtime.
6. What is the
package.json
file?The
package.json
file is a configuration file in JavaScript projects that defines the project metadata (e.g., name, version, dependencies) and how the package is structured. It also specifies the entry points (main
,module
,exports
) that tell Node.js or the browser which files to load.7. What is the
exports
field inpackage.json
?The
exports
field is a more modern way to define entry points in a package. It allows specifying different entry points for different environments (e.g., browser vs. Node.js, or ES Module vs. CommonJS). This field takes precedence overmain
andmodule
and helps avoid issues when resolving modules.8. What is Node.js?
Node.js is a runtime environment that allows you to run JavaScript on the server. It's widely used for building backend services, tools, and even desktop applications. Node.js primarily used CommonJS in the past, but it now supports ES Modules as well.
9. What is the problem this pull request solves?
The pull request addresses an issue where the library wasn't compatible with some frameworks (like Astro) because it didn't support CommonJS modules. By transforming the library into a dual-package that supports both CommonJS and ES Modules, it ensures compatibility across a wider range of environments.
10. What is Rollup?
Rollup is a JavaScript module bundler that compiles small pieces of code into something larger and more complex, like a library or application. It's particularly good at bundling ES Modules and is used to generate both CommonJS and ES Module versions of a library.
11. What changes were made to the build system?
The build system was updated to use Rollup, which allows us to generate both CommonJS and ES Module versions of the library. Additionally, the
package.json
was updated with theexports
field to clearly define entry points for different environments.12. Why did Astro fail to build before?
Astro failed to build because it was trying to load a CommonJS file (
index.cjs.js
) as an ES Module due to the way Node.js resolves modules. By adding specific file extensions and using theexports
field inpackage.json
, we can avoid this issue and ensure Astro loads the correct module format.Proposed Changes
exports
to package.jsonChecklist
Additional Info
** any additional useful context or info **
Screenshots