I'm getting my hands dirty with Babel for the 1st time to convert Jest tests from ES6 syntax to commonJS; this will likely involve using the #babel/plugin-transform-modules-commonjs babel plugin which I'm trying to install in my Next.js project. Looking at this part of Babel's configuration docs, I see the term package pop up a lot.
Are package hierarchies a Babel convention, Node-defined feature, or part of base JavaScript itself? What exactly defines a package in this context, and where is there documentation for them? Is babel-jest a stable alternative to this problem?
Babel uses a package.json file to resolve module dependencies. A package is a collection of files which can be imported using the require() function. You can read more about packages in the Node.js documentation on packages.
There is no standard way to define a package hierarchy, but Babel does have some conventions for how to organize your files. You can read more about that in the Babel documentation on organizing your code. Babel-jest is a stable alternative to converting Jest tests from ES6 syntax to commonJS. It provides support for using babel-plugin-transform-modules-commonjs to convert your modules to CommonJS.
Specifically, in the context of the Babel documentation you mentioned, the word "package" refers to your application itself (which is also considered a package) as well as other applications contained within the same repository (in case you have a monorepo containing many applications).
Related
Is it possible for an npm package to offer both ES5 and ES6 versions? I know that it's possible to target different module systems, i.e. link CommonJS via package.main and ESM via package.module.
It seems like a big inefficiency when you have a project that targets ES6 but have to load libs which are compiled to ES5, but were actually written in ES6 or later.
I'm asking as a package creator.
What is the difference between these two packages:
#vue/cli-plugin-unit-jest
vue-jest
If I have one is the other unnecessary? If so, when should one use one or the other?
Jest is JS testing framework and understands only JS.
So vue-jest is used to transform the SFC(.vue) file to a format understandable by jest. Its job ends there.
On the other hand, #vue/cli-plugin-unit-jest is the webpack type plugin that does more things in addition to just transforming the code and has deeper level integration with vue cli. It internally uses vue-jest to achieve some level of functionality.
Capabilities of #vue/cli-plugin-unit-jest includes
Transforms your vue files to JS to be feed to jest.
creating a boilerplate jest setup with example tests when installed.
Adding all the eslint and package dependencies.
providing wrappers to run the jest tests which provide specific hints to babel to avoid build issues.
When publishing some javascript to npm as a library, should I set the "main" in pacakge.json to "dist/index.js" or my "src/index.js"?
Suppose that the library is built with webpack, and may be used with projects in webpack.
what will be the difference between two options. will webpack be able to do tree shaking in both options?
Thanks!
If your library is designed to be used in the browser, then it's important to remember that not everyone is using a module bundler.
It's good practice to set the main property to the bundled file (in your case dist/index.js) and make sure that you have a prepublish script that performs your build step before you publish it.
To support tree-shaking with bundlers like Rollup, you can use the module property and ensure that it points to a module that uses ES2015 imports.
For example:
{
"main": "dist/index.js",
"module": "src/index.js"
}
Rollup will respect this, but getting Webpack to tree-shake your code is a little more involved.
I've seen some npm packages (vue for example) have a module field in their package.json.
But module is not included in the package.json documentation - is this a convention of some kind? Is there documentation for this somewhere?
Update: April 2022
The module field is not officially defined by Node.js and support is not planned. Instead, the Node.js community settled on package exports which they believe is more versatile.
For practical reasons JavaScript bundlers will continue to support the module field. The esbuild docs explain when to use module as well as related fields main and browser.
Original Answer
Is "module" an official npm property or is this a convention of some kind?
It's a proposal, but likely to be supported due to de facto usage.
Is there documentation for this somewhere?
There is, in fact, and it can be found right here and later removed here.
What's it for?
ES6 Module Interoperability in Node. Additional discussion can be found here and here. And here's a blog post from Rich Harris talking more about it.
This is used by bundler tools for ESM (ECMAScript Module) detection. The Rollup documentation says it pretty well:
If your package.json file also has a module field, ES6-aware tools
like Rollup and webpack 2 will import the ES6 module version directly.
This article on Rollup 1.0 says it another way:
The main field makes sure that Node users using require will be served the UMD version. The module field is not an official npm feature but a common convention among bundlers to designate how to import an ESM version of our library.
Further discussion of pkg.module is on the Rollup Github Wiki and the webpack Docs.
Quick question. I am a bit confused about ES2015(ES6).
Let's say I use Babel to compile to ES6 Javascript to compliant ES5 for current browsers.
The import/export functions are already available in ES6 by using Babel. So why would I need something like Browserify or Webpack if I were to simply use these just to bundle my modules, when ES6 could do it for me?
Everywhere I go I see people using Babel in combination with Browserify or Webpack. Although I know something like Webpack can be used for more, but I wonder if it is also possible to bundle files using the ES6 syntax.
I might be totally in the wrong here and I might have gotten lost in the Javascript Jungle of 2016, so I hope someone can clarifty this for me.
Edit
Am I right to assume that the native ES6 import / export functionality simply does not bundle files? From what I have read so far I think you still need to include all the separate Javascript files but you simply import modules into each-others namespace by using the native import functionality?
Yes, using babel to transpile your ES6 imports into ES5 will work.
However, one advantage of using webpack is that creates one static file to be served up in your production environment.
Pre-ES6 has no native module system, so there are multiple systems constructed in userland code (e.g. CommonJS / Node modules and AMD). Those are what Babel converts ES6 module syntax to (and yes, you're correct that ES6 module syntax has no native bundling story anyway). Browsers have no knowledge of those userland APIs. Node implements its module system by wrapping a "module" in a function that injects require() etc. In a browser require() would just be a reference error. Browserify (or another bundler) makes it work in the browser, and bundles a whole dependency graph into a single script. So if the code is for the browser you're likely going to want to bundle it. If it's for Node you may not need to.
The import/export functions
Not functions, declarations.
if I were to simply use these just to bundle my modules, when ES6 could do it for me?
I wonder if it is also possible to bundle files using the ES6 syntax.
Am I right to assume that the native ES6 import / export functionality simply does not bundle files?
Yes. There's no native way to bundle ES6 modules. You can transpile ES6 module syntax to something like Node modules and bundle those.
From what I have read so far I think you still need to include all the separate Javascript files but you simply import modules into each-others namespace by using the native import functionality?
It's important to realize that while the syntax is standardized, a lot of the behavior isn't. There's a Loader spec under development to specify how modules will actually be located and loaded.
See also https://stackoverflow.com/a/33044085/1034448.