Is it still necessary to put in so much work to precompile packages for NPM?

As I delve into a new project, the idea of numerous npm packages looms ahead. However, my approach is shifting towards eliminating pre-compiled files. Within the src directories of these packages, only d.ts, ts, js, and mjs files will reside - a radical departure from tradition motivated by both laziness and a belief that the time has come to halt pre-compilation entirely.

The question arises: how many variations must be tailored? ESModules, AMD, CommonJs, SystemJS? My simple inclination suggests leaving it untouched (import x from 'x', export foo = 123), entrusting developers with the necessary tools (Babel, Typescript) to handle integration efficiently, wouldn't you agree?

The second quandary stands at the brink: to what extent should these packages be compiled? Should we aim for ES3 or push forward to ES6 compatibility, catering solely to users on modern browsers? Is implementing differential loading the key solution here, despite its common association with HTML files rather than selectively used developer packages?

To simplify, do we truly need to invest extensive effort in this regard? Where does the lowest common denominator lie currently? While concrete statistical data eludes me, it appears that most projects employ some form of compiler/preprocessor like Babel or PostCss. What are your thoughts on this matter?

Answer №1

In today's technological landscape, CommonJS and ES modules stand out as crucial technologies. Opting to forego CommonJS means you can navigate without the need for transpilation. Nevertheless, many frameworks and libraries still heavily rely on CommonJS and are unable to utilize ES modules.

To take a more lightweight approach, consider the following steps:

Firstly: Start by defaulting to writing everything as ES modules and structuring your package to be utilized primarily as ES module(s) (e.g., specify "type":"module" in your package.json and use .mjs as the file extension).

Next: Utilize Babel solely to generate a CommonJS fallback of your modules. The process may entail:

Integrate the subsequent dev dependencies into your project:

npm install --save-dev @babel/cli @babel/core @babel/plugin-syntax-import-meta @babel/plugin-transform-modules-commonjs

Subsequently, insert the following snippet into your package.json:

"babel": {
    "plugins": [
        [ "@babel/plugin-transform-modules-commonjs" ],
        [ "@babel/plugin-syntax-import-meta" ]
    ]
}

You can then transpile your ES modules to CommonJS using a simple line of shell code:

# assuming that your ES modules reside within the lib/ directory
for script in $(find lib/ -iname '*.mjs' | grep -v test.mjs | sed -e 's|.mjs||g'); do
    npx babel $script.mjs > $script.cjs
done

This process can also be added as a script in your package.json.

"scripts": {
    "build": "for script in $(find lib/ -iname '*.mjs' | grep -v test.mjs | sed -e 's|.mjs||g'); do npx babel $script.mjs > $script.cjs; done"
}

Execute this by running npm run build, incorporating it as a commit hook, executing it before pushing to the NPM registry, or even building to a separate folder from where your ES modules exist and excluding that folder via .gitignore.

This technique was how I developed several of my libraries (due to the same reasons mentioned), and it functions seamlessly in both CommonJS and ES module environments.

On another note, NodeJS offers documentation on deploying packages as both ES modules and CommonJS: https://nodejs.org/api/esm.html#esm_dual_commonjs_es_module_packages

Answer №2

When considering your audience and the technology they use, it's important to keep in mind compatibility issues. For instance, if you are coding with language features supported by Node v19 but not by Node v12, integrating your code could potentially break their application.

What is currently the lowest common denominator?

By pre-transpiling your code and defining the lowest-supported platform using browserslist, you can ensure that any unsupported features will be polyfilled with core-js or transpiled with tools like Babel, avoiding any potential code breaks.

The answer to "what is currently the lowest common denominator" is unique to each product and business. Some applications can set their own minimum requirements, while others must cater to a wider audience with varying tech capabilities.


As for "how many variations to make," focusing on creating versions in es and commonjs is advisable. Users can benefit from the more modern syntax of es (even when transpiled), with the hope that the usage of commonjs will eventually phase out completely, possibly within the next ~5 years as of 2023.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Working with DOM Element Selections in AngularJS

After spending a day searching for ways to perform DOM selection in AngularJs, I came across the following code snippet: var elem = angular.element(document.querySelector("#myDiv")); elem.removeClass("selected"); I'm still unsure if AngularJs of ...

Is it guaranteed that npm install will consistently fetch the most recent *compatible* version of a dependency?

Even after carefully going through the documentation, I'm still a bit confused about this concept. For example, if I were to specify "dependencies": {"some_package": ^3.1.1} in my package.json, and the latest compatible version ...

"Searching for the index of a clicked element? Here's how to do

I am trying to determine the index of a clicked anchor element in my navigation using jQuery. However, when I use the following code snippet, I always get zero in the console: $('.navigation ul li a').click(function(e) { e.preventDefault(); ...

Transmit information through a socket and await a response

I am looking to implement the following steps: 1. Establish a connection to a UDP or TCP protocol. 2. Send data to a specified IP address. 3. Receive data from the specified IP address. 4. Store the received data in a variable. The task at hand involves ...

jquery method to make entire navigation bar clickable

I have a single menu bar. I recently discovered an interesting way to make the entire menu bar area clickable using jQuery. Design code snippet: <%@ Control Language="C#" AutoEventWireup="true" CodeFile="MenuControl.ascx.cs" Inherits="MenuControl"%> ...

Using lambdas in JSX attributes is not allowed because it can negatively impact rendering performance

I encountered an error when using the following code:- <FieldArray name="amenities" render={arrayHelpers => ( <div> {values.amenitieslist && values.amenitieslist.length > 0 ? ( val ...

Unusual shadow cast by the box's silhouette

I am currently facing an issue with a box and its shadow. When I close the box, a different shadow lingers behind. I have tried troubleshooting this problem but cannot pinpoint the source. I have included the relevant code files in the specified folders. I ...

Using the ngClass directive with a conditional statement: Select 'class1' if true, otherwise select 'class2'

i am currently experimenting with this piece of code <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script> <button [ngClass]="{'btn': showDirectiveContent === false ? 'btn btn-danger ...

Using .after() in AngularJS for nested ng-repeat recursive iteration

I have a straightforward layout function adjustLinks($scope) { $scope.links = [ { text: 'Menu Item 1', url: '#', },{ text: 'Menu Item 2', url: '#' ...

Package.json file missing in root directory causing absence of readme data

In my organizational system, there are two main folders: Build and Source. All things related to Grunt, npm, bower, and composer can be found in the Build Folder. The Source Folder contains all sources, while everything specific to the project (such as REA ...

What is the best way to determine the quantity of request query parameters in an express.js application?

Currently, I find myself needing to individually verify each potential parameter. if (req.query.param1 !== undefined ) { } if (req.query.param2 !== undefined ) { } if (req.query.param3 !== undefined ) { } ... ...

Tips for validating an object with unspecified properties in RunTypes (lowercase object type in TypeScript)

Can someone please confirm if the following code is correct for validating an object: export const ExternalLinks = Record({}) I'm specifically asking in relation to the repository. ...

"Encountering the error of 'require is not defined' in an Electron-React-Webpack-Typescript application when utilizing

When I add these lines to /src/renderer.ts in an Electron-React-Webpack-Typescript app: ipcRenderer.on('messageFromMain', (event, message) => { console.log(`This is the message from the second window sent via main: ${message}`); }); I encou ...

Using optional function arguments with destructured arguments in TypeScript can result in throwing an error

interface Type1 { attr1: string; attr2: string; } interface Type2 { attr1: string; attr2: string; attr3: string; // additional attribute } function fn(config: Type1 | Type2): void { // The error code is displayed above. I am ...

React search form submits separate search each time a new input is is added to the form

A unique approach is being used to dynamically create the search form by making an ajax call for the inputs. Each input can be used alone or in combination with others to refine the search results. The issue arises when the submit method triggers a new sea ...

The connection between two arrays remains intact even after using the .push() method in JavaScript or Vue.js

I need help setting up two arrays containing dates. The first array should have the dates in string format, while the second array should contain the same dates but as date objects. methods: { test() { let employments = [ { begin: ...

Using addClass and fadeIn simultaneously when hovering over an element

After writing JavaScript code that utilizes the JQuery library to swap classes on hover, I noticed that the transition between background images was quite abrupt. The code functions as intended, but I would prefer to incorporate a fadeIn and fadeOut effect ...

What are the steps for implementing Kotlin + React + Redux with create-react-kotlin-app?

I am currently utilizing the create-react-kotlin-app tool and following the step-by-step guide available on its official GitHub repository, in order to develop a React + Redux application using Kotlin. The initial installation steps proceeded smoothly: cr ...

Running an npm audit on the project reveals numerous errors and vulnerabilities

After running npm audit on my React project, I was presented with an extensive list of issues that needed attention. # npm audit report postcss 7.0.0 - 8.2.9 Severity: moderate Regular Expression Denial of Service - https://npmjs.com/advisories/1693 fix ...

Facing a problem with the carousel in Angular 6

I am currently working with Angular 6 and I have a topAdvertisementList[] that is supposed to return 2 records to be displayed in my carousel with a fixed image, but for some reason, only one record is showing up in the carousel! I suspect there might be a ...