Making NPM package available to ES6 and ECMAScript - javascript

I'm making an NPM package in TypeScript, and wanted to know how I can make it available for ES and Node modules.
I've set it up with Rollup and a few configs:
rollup.config.js
export default {
input: 'build/kimp.js', // built from TS
output: [
{
file: 'dist/main/kimp.js',
format: 'es',
strict: false,
name: 'module',
banner: `#! /usr/bin/env node - Copyright 2020 Herbie Vine - Updated: ${new Date()}`
},
{
file: 'dist/module/kimp.js',
format: 'umd',
strict: false,
name: 'common',
banner: `#! /usr/bin/env node - Copyright 2020 Herbie Vine - Updated: ${new Date()}`
}
],
plugins: [
terser(),
resolve(),
json(),
commonjs({
include: 'node_modules/**'
})
],
external: [
'crypto'
]
};
package.json
{
"name": "kimp",
"version": "1.0.0",
"description": "Lightweight ID generator",
"sideEffects": false,
"main": "dist/main/kimp.js", // import() - es6
"module": "dist/module/kimp.js", // require() - node
"scripts": {
"build": "tsc -p ./src/tsconfig.json",
"rollup": "rollup -c"
},
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
},
"keywords": [...],
"repository": {...},
"author": "Herbie Vine",
"license": "MIT",
"bugs": {...},
"homepage": "https://github.com/herbievine/kimp#readme",
"devDependencies": {...}
}
I tried using it in an express app, but I get an error:
const { kimp } = require('kimp');
console.log(kimp)
------
C:\Users\**\kimp-ts\dist\main\kimp.js:3484
export { kimp };
^^^^^^
This is coming from the built version for es modules
basic gist on github
Am I wrong to believe that when node requires a package, it looks at the module key in package.json. Anyways I've been at it for hours, any help would mean a lot cheers đź‘Ť

Using rollup you have compiled in to ESModules as you have specified format: 'es' in your rollup.config.js. Nodejs uses commonjs modules and require is supposed to import the commonjs module which it couldn't find there and hence you are getting error. Nodejs started shipping experimental support for ES modules starting node version 10.
If you have greater than version node 10 you can just update your express server start script in package.json to allow the experimental modules support for instance: "start": "node --experimental-modules server.js".
Other approaches that can work depending on your liking or requirements:
Use the third party #std/esm to compile and use es modules as commonjs modules
Compile your library in commonjs modules via this rollup plugin
Edit: It seems the above code in question had issue in config and which fixed the issue, main and module entries in package.json were declared other way around and had to swap the entries to set them up correctly. Main should actually point to umd and module should point to es modules.

Related

How to import js module when Typescript declaration file is located in a separate directory?

Question:
When I run npm run build with the configuration below, rollup.js is unable to resolve the dependency (import) and displays the following message below. Is there any way to make rollup happy while also referencing the Typescript declaration file?
Message from rollup:
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
pdfjs-dist/types/web/ui_utils (imported by index.ts)
Here is my index.ts:
import { RendererType } from 'pdfjs-dist/types/web/ui_utils'
const renderType = RendererType.CANVAS;
My package.json:
{
"name": "myproject",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "rollup --config"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"#rollup/plugin-node-resolve": "^13.2.1",
"#rollup/plugin-typescript": "^8.3.2",
"pdfjs-dist": "^2.13.216",
"rollup": "^2.70.2",
"typescript": "^4.6.4"
}
}
My rollup.config.js:
import typescript from '#rollup/plugin-typescript';
import { nodeResolve } from '#rollup/plugin-node-resolve';
export default [
{
input: 'index.ts',
output: {
format: 'es',
file: 'index.js'
},
plugins: [
typescript(),
nodeResolve({ browser: true })
]
}
]
Here are the exact steps to reproduce the error above:
Create an empty folder and then run npm -y init
Run the following command:
npm install typescript pdfjs-dist rollup #rollup/plugin-node-resolve #rollup/plugin-typescript --save-dev
Add "build": "rollup --config" to your package.json
Create the rollup.config.js file shown above
Run npm run build in the terminal
More background:
Now, I should point out that the file pdfjs-dist/types/web/ui_utils is a typescript declaration file (ui_utils.d.ts). The actual js file is in pdfjs-dist/lib/web.
If I copy the typescript declaration file so that it is located in the same directory as the js file, dependency resolution works. However, since I will be writing a wrapper around pdf js, I would have to do this for every typescript declaration file which is very tedious and upgrading would also become an issue.
So another way to word the question would be how to resolve a module *.d.ts when the js file is located in another directory?
I came up with the following solution to the problem.
Create a d.ts with the following and name it the same as the module name (ui_utils.d.ts in my case)
declare module 'pdfjs-dist/lib/web/ui_utils' {
export * from 'pdfjs-dist/types/web/ui_utils'
}
Using the above, now I can reference the actual location of the module and Typescript will pick up the declarations as well.
import { RendererType } from 'pdfjs-dist/lib/web/ui_utils'
Side note: When using rollup, you may also need to use #rollup/plugin-commonjs to be able to resolve dependencies.

ReferenceError: regeneratorRuntime is not defined working on vanilla js [duplicate]

I'm trying to use async/await from scratch on Babel 6, but I'm getting regeneratorRuntime is not defined.
.babelrc file
{
"presets": [ "es2015", "stage-0" ]
}
package.json file
"devDependencies": {
"babel-core": "^6.0.20",
"babel-preset-es2015": "^6.0.15",
"babel-preset-stage-0": "^6.0.15"
}
.js file
"use strict";
async function foo() {
await bar();
}
function bar() { }
exports.default = foo;
Using it normally without the async/await works just fine. Any ideas what I'm doing wrong?
babel-polyfill (deprecated as of Babel 7.4) is required. You must also install it in order to get async/await working.
npm i -D babel-core babel-polyfill babel-preset-es2015 babel-preset-stage-0 babel-loader
package.json
"devDependencies": {
"babel-core": "^6.0.20",
"babel-polyfill": "^6.0.16",
"babel-preset-es2015": "^6.0.15",
"babel-preset-stage-0": "^6.0.15"
}
.babelrc
{
"presets": [ "es2015", "stage-0" ]
}
.js with async/await (sample code)
"use strict";
export default async function foo() {
var s = await bar();
console.log(s);
}
function bar() {
return "bar";
}
In the startup file
require("babel-core/register");
require("babel-polyfill");
If you are using webpack you need to put it as the first value of your entry array in your webpack configuration file (usually webpack.config.js), as per #Cemen comment:
module.exports = {
entry: ['babel-polyfill', './test.js'],
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.jsx?$/, loader: 'babel', }
]
}
};
If you want to run tests with babel then use:
mocha --compilers js:babel-core/register --require babel-polyfill
Note
If you're using babel 7, the package has been renamed to #babel/plugin-transform-runtime.
Besides polyfill, I use babel-plugin-transform-runtime. The plugin is described as:
Externalize references to helpers and builtins, automatically polyfilling your code without polluting globals. What does this actually mean though? Basically, you can use built-ins such as Promise, Set, Symbol etc as well use all the Babel features that require a polyfill seamlessly, without global pollution, making it extremely suitable for libraries.
It also includes support for async/await along with other built-ins of ES 6.
$ npm install --save-dev babel-plugin-transform-runtime
In .babelrc, add the runtime plugin
{
"plugins": [
["transform-runtime", {
"regenerator": true
}]
]
}
Babel 7 Users
I had some trouble getting around this since most information was for prior babel versions. For Babel 7, install these two dependencies:
npm install --save #babel/runtime
npm install --save-dev #babel/plugin-transform-runtime
And, in .babelrc, add:
{
"presets": ["#babel/preset-env"],
"plugins": [
["#babel/transform-runtime"]
]
}
Update
It works if you set the target to Chrome. But it might not work for other targets, please refer to: https://github.com/babel/babel-preset-env/issues/112
So this answer is NOT quite proper for the original question. I will keep it here as a reference to babel-preset-env.
A simple solution is to add import 'babel-polyfill' at the beginning of your code.
If you use webpack, a quick solution is to add babel-polyfill as shown below:
entry: {
index: ['babel-polyfill', './index.js']
}
I believe I've found the latest best practice.
Check this project: https://github.com/babel/babel-preset-env
yarn add --dev babel-preset-env
Use the following as your babel configuration:
{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 Chrome versions"]
}
}]
]
}
Then your app should be good to go in the last 2 versions of Chrome browser.
You can also set Node as the targets or fine-tune the browsers list according to https://github.com/ai/browserslist
Tell me what, don't tell me how.
I really like babel-preset-env's philosophy: tell me which environment you want to support, do NOT tell me how to support them. It's the beauty of declarative programming.
I've tested async await and they DO work. I don't know how they work and I really don't want to know. I want to spend my time on my own code and my business logic instead. Thanks to babel-preset-env, it liberates me from the Babel configuration hell.
Update: The Babel 7 post also has a more in-depth answer.
Babel 7.4.0 or later (core-js 2 / 3)
As of Babel 7.4.0, #babel/polyfill is deprecated.
In general, there are two ways to install polyfills/regenerator: via global namespace (Option 1) or as ponyfill (Option 2, without global pollution).
Option 1: #babel/preset-env
presets: [
["#babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3, // or 2,
"targets": {
"firefox": "64", // or whatever target to choose .
},
}]
]
will automatically use regenerator-runtime and core-js according to your target. No need to import anything manually. Don't forget to install runtime dependencies:
npm i --save regenerator-runtime core-js
Alternatively, set useBuiltIns: "entry" and import it manually:
import "regenerator-runtime/runtime";
import "core-js/stable"; // if polyfills are also needed
Option 2: #babel/transform-runtime with #babel/runtime
This alternative has no global scope pollution and is suitable for libraries.
{
"plugins": [
[
"#babel/plugin-transform-runtime",
{
"regenerator": true,
"corejs": 3 // or 2; if polyfills needed
...
}
]
]
}
Install it:
npm i -D #babel/plugin-transform-runtime
npm i #babel/runtime
If corejs polyfill is used, you replace #babel/runtime with #babel/runtime-corejs2 (for "corejs": 2) or #babel/runtime-corejs3 (for "corejs": 3).
Alternatively, if you don't need all the modules babel-polyfill provides, you can just specify babel-regenerator-runtime in your webpack config:
module.exports = {
entry: ['babel-regenerator-runtime', './test.js'],
// ...
};
When using webpack-dev-server with HMR, doing this reduced the number of files it has to compile on every build by quite a lot. This module is installed as part of babel-polyfill so if you already have that you're fine, otherwise you can install it separately with npm i -D babel-regenerator-runtime.
My simple solution:
npm install --save-dev babel-plugin-transform-runtime
npm install --save-dev babel-plugin-transform-async-to-generator
.babelrc
{
"presets": [
["latest", {
"es2015": {
"loose": true
}
}],
"react",
"stage-0"
],
"plugins": [
"transform-runtime",
"transform-async-to-generator"
]
}
This error is caused when async/await functions are used without the proper Babel plugins. As of March 2020, the following should be all you need to do. (#babel/polyfill and a lot of the accepted solutions have been deprecated in Babel. Read more in the Babel docs.)
In the command line, type:
npm install --save-dev #babel/plugin-transform-runtime
In your babel.config.js file, add this plugin #babel/plugin-transform-runtime. Note: The below example includes the other presets and plugins I have for a small React/Node/Express project I worked on recently:
module.exports = {
presets: ['#babel/preset-react', '#babel/preset-env'],
plugins: ['#babel/plugin-proposal-class-properties',
'#babel/plugin-transform-runtime'],
};
babel-regenerator-runtime is now deprecated, instead one should use regenerator-runtime.
To use the runtime generator with webpack and babel v7:
install regenerator-runtime:
npm i -D regenerator-runtime
And then add within webpack configuration :
entry: [
'regenerator-runtime/runtime',
YOUR_APP_ENTRY
]
Update your .babelrc file according to the following examples, it will work.
If you are using #babel/preset-env package
{
"presets": [
[
"#babel/preset-env", {
"targets": {
"node": "current"
}
}
]
]
}
or if you are using babel-preset-env package
{
"presets": [
[
"env", {
"targets": {
"node": "current"
}
}
]
]
}
As of Oct 2019 this worked for me:
Add this to the preset.
"presets": [
"#babel/preset-env"
]
Then install regenerator-runtime using npm.
npm i regenerator-runtime
And then in your main file use: (this import is used only once)
import "regenerator-runtime/runtime";
This is will enable you to use async awaits in your file and remove the regenerator error
Be careful of hoisted functions
I had both my 'polyfill import' and my 'async function' in the same file, however I was using the function syntax that hoists it above the polyfill which would give me the ReferenceError: regeneratorRuntime is not defined error.
Change this code
import "babel-polyfill"
async function myFunc(){ }
to this
import "babel-polyfill"
var myFunc = async function(){}
to prevent it being hoisted above the polyfill import.
If using babel-preset-stage-2 then just have to start the script with --require babel-polyfill.
In my case this error was thrown by Mocha tests.
Following fixed the issue
mocha \"server/tests/**/*.test.js\" --compilers js:babel-register --require babel-polyfill
I had this problem in Chrome. Similar to RienNeVaPlu͢s’s answer, this solved it for me:
npm install --save-dev regenerator-runtime
Then in my code:
import 'regenerator-runtime/runtime';
Happy to avoid the extra 200 kB from babel-polyfill.
I used tip from https://github.com/babel/babel/issues/9849#issuecomment-592668815 and added targets: { esmodules: true,} to my babel.config.js.
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
esmodules: true,
},
},
],
],
}
You're getting an error because async/await use generators, which are an ES2016 feature, not ES2015. One way to fix this is to install the babel preset for ES2016 (npm install --save babel-preset-es2016) and compile to ES2016 instead of ES2015:
"presets": [
"es2016",
// etc...
]
As the other answers mention, you can also use polyfills (though make sure you load the polyfill first before any other code runs). Alternatively, if you don't want to include all of the polyfill dependencies, you can use the babel-regenerator-runtime or the babel-plugin-transform-runtime.
I started getting this error after converting my project into a typescript project. From what I understand, the problem stems from async/await not being recognized.
For me the error was fixed by adding two things to my setup:
As mentioned above many times, I needed to add babel-polyfill into my webpack entry array:
...
entry: ['babel-polyfill', './index.js'],
...
I needed to update my .babelrc to allow the complilation of async/await into generators:
{
"presets": ["es2015"],
"plugins": ["transform-async-to-generator"]
}
DevDependencies:
I had to install a few things into my devDependencies in my package.json file as well. Namely, I was missing the babel-plugin-transform-async-to-generator, babel-polyfill and the babel-preset-es2015:
"devDependencies": {
"babel-loader": "^6.2.2",
"babel-plugin-transform-async-to-generator": "^6.5.0",
"babel-polyfill": "^6.5.0",
"babel-preset-es2015": "^6.5.0",
"webpack": "^1.12.13"
}
Full Code Gist:
I got the code from a really helpful and concise GitHub gist you can find here.
I fixed this error by installing babel-polyfill
npm install babel-polyfill --save
then I imported it in my app entry point
import http from 'http';
import config from 'dotenv';
import 'babel-polyfill';
import { register } from 'babel-core';
import app from '../app';
for testing I included --require babel-polyfill in my test script
"test": "export NODE_ENV=test|| SET NODE_ENV=test&& mocha --compilers
js:babel-core/register --require babel-polyfill server/test/**.js --exit"
There are so many answers up there, I will post my answer for my reference.
I use webpack and react, here is my solution without the .babelrc file
I am working on this in Aug 2020
Install react and babel
npm i #babel/core babel-loader #babel/preset-env #babel/preset-react react react-dom #babel/plugin-transform-runtime --save-dev
Then in my webpack.config.js
// other stuff
module.exports = {
// other stuff
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env',"#babel/preset-react"],
plugins: ['#babel/plugin-proposal-class-properties', '#babel/plugin-transform-runtime'],
//npm install --save-dev #babel/plugin-transform-runtime
}
}
},
],
},
};
I just don't know why I dont need to install the async package for the moment
New Answer Why you follow my answer ?
Ans: Because I am going to give you a answer with latest Update version npm project .
04/14/2017
"name": "es6",
"version": "1.0.0",
"babel-core": "^6.24.1",
"babel-loader": "^6.4.1",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"webpack": "^2.3.3",
"webpack-dev-server": "^2.4.2"
If your Use this version or more UP version of Npm and all other ...
SO just need to change :
webpack.config.js
module.exports = {
entry: ["babel-polyfill", "./app/js"]
};
After change webpack.config.js files Just add this line to top of your code .
import "babel-polyfill";
Now check everything is ok. Reference LINK
Also Thanks #BrunoLM for his nice Answer.
The targeted browsers I need to support already support async/await, but when writing mocha tests, without the proper setting I still got this error.
Most of the articles I googled are outdated, including the accepted answer and high voted answers here, i.e. you don't need polyfill, babel-regenerator-runtime, babel-plugin-transform-runtime. etc. if your target browser(s) already supports async/await (of course if not you need polyfill)
I don't want to use webpack either.
Tyler Long's answer is actually on the right track since he suggested babel-preset-env (but I omitted it first as he mentioned polifill at the beginning). I still got the ReferenceError: regeneratorRuntime is not defined at the first then I realized it was because I didn't set the target. After setting the target for node I fix the regeneratorRuntime error:
"scripts": {
//"test": "mocha --compilers js:babel-core/register"
//https://github.com/mochajs/mocha/wiki/compilers-deprecation
"test": "mocha --require babel-core/register"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-preset-env": "^1.7.0",
"mocha": "^5.2.0"
},
//better to set it .bablerc, I list it here for brevity and it works too.
"babel": {
"presets": [
["env",{
"targets": {
"node": "current"
"chrome": 66,
"firefox": 60,
},
"debug":true
}]
]
}
My working babel 7 boilerplate for react with regenerator runtime:
.babelrc
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": true,
},
},
],
"#babel/preset-react",
],
"plugins": [
"#babel/plugin-syntax-class-properties",
"#babel/plugin-proposal-class-properties"
]
}
package.json
...
"devDependencies": {
"#babel/core": "^7.0.0-0",
"#babel/plugin-proposal-class-properties": "^7.4.4",
"#babel/plugin-syntax-class-properties": "^7.2.0",
"#babel/polyfill": "^7.4.4",
"#babel/preset-env": "^7.4.5",
"#babel/preset-react": "^7.0.0",
"babel-eslint": "^10.0.1",
...
main.js
import "#babel/polyfill";
....
Easiest way to fix this 'regeneratorRuntime not defined issue' in your console:
You don't have to install any unnecessary plugins. Just add:
<script src="https://unpkg.com/regenerator-runtime#0.13.1/runtime.js"></script>
inside of the body in your index.html.
Now regeneratorRuntime should be defined once you run babel and now your async/await functions should be compiled successfully into ES2015
Just install regenerator-runtime
with below command
npm i regenerator-runtime
add below line in startup file before you require server file
require("regenerator-runtime/runtime");
So far this has been working for me
I get this error using gulp with rollup when I tried to use ES6 generators:
gulp.task('scripts', () => {
return rollup({
entry: './app/scripts/main.js',
format: "iife",
sourceMap: true,
plugins: [babel({
exclude: 'node_modules/**',
"presets": [
[
"es2015-rollup"
]
],
"plugins": [
"external-helpers"
]
}),
includePaths({
include: {},
paths: ['./app/scripts'],
external: [],
extensions: ['.js']
})]
})
.pipe(source('app.js'))
.pipe(buffer())
.pipe(sourcemaps.init({
loadMaps: true
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('.tmp/scripts'))
.pipe(reload({ stream: true }));
});
I may case the solution was to include babel-polyfill as bower component:
bower install babel-polyfill --save
and add it as dependency in index.html:
<script src="/bower_components/babel-polyfill/browser-polyfill.js"></script>
1 - Install babel-plugin-transform-async-to-module-method,
babel-polyfil, bluebird , babel-preset-es2015, babel-core :
npm install babel-plugin-transform-async-to-module-method babel-polyfill bluebird babel-preset-es2015 babel-core
2 - Add in your js babel polyfill:
import 'babel-polyfill';
3 - Add plugin in your .babelrc:
{
"presets": ["es2015"],
"plugins": [
["transform-async-to-module-method", {
"module": "bluebird",
"method": "coroutine"
}]
]
}
Source : http://babeljs.io/docs/plugins/transform-async-to-module-method/
For people looking to use the babel-polyfill version 7^ do this with webpack ver3^.
Npm install the module npm i -D #babel/polyfill
Then in your webpack file in your entry point do this
entry: ['#babel/polyfill', path.resolve(APP_DIR, 'App.js')],
To babel7 users and ParcelJS >= 1.10.0 users
npm i #babel/runtime-corejs2
npm i --save-dev #babel/plugin-transform-runtime #babel/core
.babelrc
{
"plugins": [
["#babel/plugin-transform-runtime", {
"corejs": 2
}]
]
}
taken from https://github.com/parcel-bundler/parcel/issues/1762
I had a setup
with webpack using presets: ['es2015', 'stage-0']
and mocha that was running tests compiled by webpack.
To make my async/await in tests work all I had to do is use mocha with the --require babel-polyfill option:
mocha --require babel-polyfill
I am using a React and Django project and got it to work by using regenerator-runtime. You should do this because #babel/polyfill will increase your app's size more and is also deprecated. I also followed this tutorial's episode 1 & 2 to create my project's structure.
*package.json*
...
"devDependencies": {
"regenerator-runtime": "^0.13.3",
...
}
.babelrc
{
"presets": ["#babel/preset-env", "#babel/preset-react"],
"plugins": ["transform-class-properties"]
}
index.js
...
import regeneratorRuntime from "regenerator-runtime";
import "regenerator-runtime/runtime";
ReactDOM.render(<App />, document.getElementById('app'));
...

Bundle JS with rollup and Babel for use in IE11

I try to bundle two JavaScript modules, so that the resulting code works in IE11. For this I have setup a yarn/npm project which uses rollup.js for bundling and Babel for transpiling. Everything works fine until I add the (non-dev) dependency core-js.
Here the details:
1 Setup before adding core-js
JS files
src/main.js
src/utils.js
Config files
package.json
{
"name": "rollup_for_ie",
"devDependencies": {
"#babel/core": "^7.11.1",
"#babel/preset-env": "^7.11.0",
"#rollup/plugin-babel": "^5.2.0",
"#rollup/plugin-node-resolve": "^9.0.0",
"rollup": "^2.24.0"
},
}
rollup.config.js
import resolve from '#rollup/plugin-node-resolve';
import babel from '#rollup/plugin-babel';
export default {
input: 'src/main.js',
output: {
file: 'dist/main.js',
format: 'iife'
},
plugins: [
resolve({
browser: true
}),
babel({
exclude: "node_modules/**", // only transpile our source code
babelHelpers: 'bundled'
})
]
};
babel.config.js
module.exports = {
presets: [
[
"#babel/preset-env",
{
targets: {
browsers: "> 0.5%, ie >= 11"
},
modules: false,
spec: true,
useBuiltIns: "usage",
forceAllTransforms: true,
corejs: 3
}
]
],
};
When I run rollup -c I get warnings about unresolved dependencies, but a bundled file dist/main.js with the (used) stuff from the src directory is generated. The resulting file works even in modern browsers like Chrome. So far so good.
Problems after adding core-js
However the bundled file is not yet IE11 ready: In IE I get errors like Object doesn't support property or method 'getOwnPropertySymbols'. So the polyfills from core-js need to be added.
For this I install core-js as a prod dependency. Now rollup -c doesn't give me warnings - but the resulting dist/main.js begins like
(function (exports) {
'use strict';
var $ = require('../internals/export');
.
.
.
which as a script can not neither Chrome nor IE execute! It looks like that somehow the presence of the core-js library throws the rollup bundler off.
How can I fix my setup so that the resulting dist/main.js works as non-module script in Chrome and IE11?
I think as you enabled the option useBuiltIns: "usage" which means it will append code from corejs into your module files which is written with cjs style. So you have to add this plugin #rollup/plugin-commonjs to convert back to esm, then it will work:
import commonjs from '#rollup/plugin-commonjs';
export default {
// ...
plugins: [
// ...
commonjs(),
]
};

Compiling React projects in MonoRepo failing

I'm trying to setup yarn workspaces with my docker instance. This is my directory structure:
/monorepo/
/node_modules/
#libs/common
#services/common
#services/project-A
...OTHER DEPS...
package.json
/services/
/common/
index.jsx
package.json
/project-A/
webpack.base.config.js
**REACT project with babel, webpack, etc**
/libs/
/tools/
/common/
index.jsx
package.json
To simplify my docker setup I just configured this volume within my docker compose that maps the entire monorepo directory:
volumes:
- '../../../monorepo:/monorepo'
From there in my Project-A I import #libs/common and #services/common. This works fine when the common libraries are exporting simple functions like:
export const Add = (a,b) => a+b
Webpack has no issue resolving this and building Project-A.
However when I try to import a component from one of the common libraries like this:
/libs/tools/common:
import React from 'react'
export MySharedComponent = () => <>HELLLO</>
I get an error in the build process:
Error: Cannot find module '/monorepo/libs/tools/common/webpack.base.config.js'
Require stack:
- /monorepo/node_modules/eslint-import-resolver-webpack/index.js
- /monorepo/node_modules/eslint-module-utils/resolve.js
- /monorepo/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
- /monorepo/node_modules/eslint-plugin-import/lib/index.js
The eslint file under Project-A:
{
"parser": "babel-eslint",
"env": {
"browser": true,
"node": true,
"jest": true,
"cypress/globals": true
},
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.base.config.js"
}
}
}
}
The babel.rc under Project-A
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "current"
}
}
],
"#babel/preset-react",
"#babel/preset-flow"
],
"env": {
"test": {
"plugins": [
[
"babel-plugin-webpack-alias",
{
"config": "./webpack.base.config.js"
}
]
]
}
}
}
My Question:
Is the main issue that there's no webpack config set up in the common repositories. Therefore the workspace does not know how to compile my shared resources?
Should there only be 1 webpack build config in my workspace used by all projects within the workspace? Currently I only have 1 config under Project-A?
What happens if I have specific webpack needs per project, does 1 config (if that's the answer) make sense?
1) First, there is a line in your code that you are referring to webpack.base.config.js in both babelrc and eslint,
so if that file does not exist, this error that says module not found makes sense.
2) Second: if you build and use your repositories in the same situation and environment, yes you can have one config for both but you might need environment setup (Development, Production) for your config.
But if you really want to make your dependencies and configs apart, webpack support multiple entries for your project which you can check that out.

How to inline Rollup/Babel polyfills for IE11

I've been working on a PHP project for a while and the client has asked for IE11 support at the last possible minute. HTML/CSS problems I can deal with but my javascript was written modern syntax.
So I install node, take my javascript, run it through Rollup & Babel the first time it's needed and cache the result for future requests.
Now the output lacks the arrow functions that were giving me a headache before but I've got a bigger problem: the polyfills are import statements and IE11 doesn't support import statements.
I feel like I need to emphasise that I'm not running a node server - it's a PHP server, I'm just using node on the backend for rollup & babel. If there's something that node does to make this work I'm not familiar with it.
Here's my rollup.config.js:
import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import minify from 'rollup-plugin-babel-minify';
export default {
input: '_dud_input.js', // These are set in the exec() call
output: {
file: '_dud_output.js', // These are set in the exec() call
format: 'iife',
strict : false
},
plugins: [
resolve({
browser: true
}),
commonjs({
sourceMap: false
}),
babel({
exclude: 'node_modules/**' // only transpile our source code
}),
minify({
"comments": false
})
]
};
And here's babel.config.js:
module.exports = {
"presets" : [
[
"#babel/preset-env",
{
"targets": {
"browsers": "> 0.5%, ie >= 11"
},
"modules": false,
"spec": true,
"useBuiltIns": "usage",
"forceAllTransforms": true,
"corejs": {
"version": 3,
"proposals": false
}
}
]
]
}
For giggles, here's the shell script I call to run the process:
#!/bin/bash
set -e
# Expected argument values:
# $1 - Path of the root directory
# $2 - Path of the node binary
# $3 - Path of the rollup binary
# $4 - Source file path
# $5 - Destination file path
if [ $# -ne 5 ]
then
exit 99
fi
ROOT_DIR=$1
NODE_BIN=$2
ROLLUP_BIN=$3
SRC_PATH=$4
DEST_PATH=$5
cd ${ROOT_DIR}
${NODE_BIN} ${ROLLUP_BIN} -c ${ROOT_DIR}/rollup.config.js -i ${SRC_PATH} -o ${DEST_PATH}
And it's linked like this:
<script defer="" type="text/javascript" src="http://example.com/site-asset/flatfile.js"></script>
With these settings, my flatfile.js outputs with the following at the top:
import"core-js/modules/es.symbol";
import"core-js/modules/es.symbol.description";
import"core-js/modules/es.symbol.iterator";
import"core-js/modules/es.array.concat";
import"core-js/modules/es.array.filter";
import"core-js/modules/es.array.find";
import"core-js/modules/es.array.for-each";
// ...etc...
Under this setup IE11's console says there's a Syntax error at the first line of every file with the import statements.
Changing useBuiltIns from usage to entry (which I understand means I'm expected to have an entry file elsewhere that adds the polyfills) and including https://polyfill.io/v3/ doesn't do anything (I get errors on Number.parseFloat() calls).
Out of desperation I even added a "core-js" route to my application, which tries to serve up the appropriate core-js file - but there's no indication that IE11 is even trying to follow the require statements.
Looking around the internet it seems like this isn't a problem for anybody else - IE11 apparently works for everybody else?
Maybe it's because I'm not using a node server, but a PHP/Apache one?
I just want the Babel to include the core-js polyfills in my files, not as require statements that IE11 doesn't know how to parse.
I had to disable the babel-minify plugin, but aside from that, copying your configuration seems to work just fine and I get a single bundled JavaScript file with no import statements.
The files are reproduced below, but the full test repo is available at https://github.com/akx/so58712204 – yarn; yarn build and look in dist/...
babel.config.js
module.exports = {
presets: [
[
"#babel/preset-env",
{
targets: {
browsers: "> 0.5%, ie >= 11"
},
modules: false,
spec: true,
useBuiltIns: "usage",
forceAllTransforms: true,
corejs: {
version: 3,
proposals: false
}
}
]
]
};
package.json
{
"scripts": {
"build": "rollup -c ./rollup.config.js -i ./src/entry.js -o ./dist/output.js"
},
"dependencies": {
"#babel/core": "^7.7.0",
"#babel/preset-env": "^7.7.0",
"core-js": "^3.3.6",
"rollup": "^1.26.3",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-babel-minify": "^9.1.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0"
}
}
rollup.config.js
import commonjs from "rollup-plugin-commonjs";
import resolve from "rollup-plugin-node-resolve";
import babel from "rollup-plugin-babel";
export default {
input: "_dud_input.js", // These are set in the exec() call
output: {
file: "_dud_output.js", // These are set in the exec() call
format: "iife",
strict: false
},
plugins: [
resolve({
browser: true
}),
commonjs({
sourceMap: false
}),
babel({
exclude: "node_modules/**" // only transpile our source code
})
]
};
src/entry.js
import { magicNumber } from "./magic";
console.log(new Set([Number.parseFloat(magicNumber)]));
src/magic.js
const magicNumber = "8.82";
export { magicNumber };

Categories

Resources