Using babel-polyfill with grunt and browserify - javascript

My grunt build system transpiles my javascript (which is using react as well).
Unfortunately it doesn't transpile Promises. For that, I need a polyfill.
I want to include babel-polyfill with my grunt build system.
My build system uses browserify along with babelify and the es2015 preset.
How do I include babel-polyfill into the mix?
Here is what I have...
Inside gruntfile.js, here is where I use browserify
browserify: {
dist: {
options: {
watch: true,
transform: [["babelify", {presets: ['es2015', 'react']}], ["envify", {NODE_ENV: 'development'}]]
},
files: {
'dist/js/app.js' : 'src/js/main.js'
}
},
build: {
options: {
transform: [["babelify", {presets: ['es2015', 'react'], compact: true }], ["envify", {NODE_ENV: 'production'}]]
},
files: {
'dist/js/app.js' : 'src/js/main.js'
}
}
},
Here is my babelrc file
{
"presets": [ "react", "es2015" ]
}
Thanks!

Assuming that babel-polyfill is included as a dependency, at the top of your entry file 'src/js/main.js' add the line:
import "babel-polyfill";
No need to do anything in your GruntFile.js

Related

How to transpile an npm dependency to es5 with babel and webpack?

I have to make our website compatible for internet explorer, and it’s quite tricky, as the browser doesn’t understand es6 (arrow functions and the like). I’ve been trying to upgrade webpack and tweak the webpack and babel config to fit our needs. This works great for our own source files, but doesn’t in the node_modules folder. The syntax is not IE compatible if we don’t include it in our babel transpiling, but it also fails if we do transpile the specific node_modules folder that fails (a dependency within the webpack-hot-middleware dependency), giving an error of Uncaught Error: ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead. I’m hoping I just have the wrong babel or webpack settings here, but I've been scraping the interwebz for answers for a while but haven't quite found the solution yet.
I'm using webpack 5 and babel-loader. I have a .babelrc and a webpack.config.js file, here is a snippet from the latter while I try to transpile the failing node_module package:
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: [
{
and: [/node_modules/],
not: [
path.resolve(
__dirname,
"node_modules/webpack-hot-middleware/node_modules/ansi-regex"
)
]
}
],
options: {
babelrc: false,
presets: [
"#babel/preset-react",
["#babel/preset-env", {
"corejs": { "version": 3 },
"useBuiltIns": "usage",
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1",
"ie": "10"
},
}]],
"plugins": [
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-proposal-optional-chaining",
"#babel/plugin-proposal-nullish-coalescing-operator",
"#babel/plugin-transform-arrow-functions"
]
}
},
[...]
]
}

How to use jest with node_modules using es6 within NX project

I have a project with NX structure(apps + libs). And I am writing tests for react + typescript lib. I faced the issue when I try to use suneditor + suneditor-react:
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
...\node_modules\suneditor\src\plugins\index.js:4
import blockquote from './command/blockquote';
I found the files are not transformed when they are in node_modules and made this change to jest config:
transformIgnorePatterns: [
"<rootDir>/node_modules/(?!suneditor|suneditor-react)"
]
After this I am continuously getting the error for all tests:
● Test suite failed to run
Cannot find module 'babel-preset-es2015'
at resolveStandardizedName (../../node_modules/#babel/core/lib/config/files/plugins.js:100:7)
at resolvePreset (../../node_modules/#babel/core/lib/config/files/plugins.js:48:10)
at loadPreset (../../node_modules/#babel/core/lib/config/files/plugins.js:67:20)
at createDescriptor (../../node_modules/#babel/core/lib/config/config-descriptors.js:154:9)
at ../../node_modules/#babel/core/lib/config/config-descriptors.js:109:50
at Array.map (<anonymous>)
at createDescriptors (../../node_modules/#babel/core/lib/config/config-descriptors.js:109:29)
at createPresetDescriptors (../../node_modules/#babel/core/lib/config/config-descriptors.js:101:10)
Jest config:
module.exports = {
displayName: 'component',
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]sx?$': 'babel-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/libs/pbc-client-journal',
transformIgnorePatterns: [
"<rootDir>/node_modules/(?!suneditor|suneditor-react)"
]
};
And jest.preset.js:
const nxPreset = require('#nrwl/jest/preset');
module.exports = { ...nxPreset };
.babelrc:
{
"presets": [
[
"#nrwl/react/babel",
{
"runtime": "automatic",
"useBuiltIns": "usage"
}
]
]
}
Could someone please help me with this issue?
You need to switch to babel.config.js in your lib to be able to transform files from node_modules. Here is what worked in my project:
babel.config.js
module.exports = {
presets: [
[
"#nrwl/react/babel",
{
runtime: "automatic",
useBuiltIns: "usage"
}
]
],
plugins: []
}
jest.config.js
module.exports = {
displayName: 'mylib',
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]sx?$': ['babel-jest', { cwd: __dirname }],
},
transformIgnorePatterns: [
"node_modules/(?!(#asyncapi)/)"
],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/libs/mylib',
};

Why is my webpack babel setup emitting ESM requires when I have configured my preset to commonjs?

Today I observed babel/babel-loader exhibiting some undesirable behavior. I am bundling some assets for usage on nodejs. Post-compile, a bundle is generated with references to #babel/runtime/**/esm/**. Of course, node cannot import such files, and on node bundle.js I get:
Must use import to load ES Module: /my/project/node_modules/#babel/runtime/helpers/esm/defineProperty.js
require() of ES modules is not supported.
Right. Makes sense. But babel-loader injected those imports. In fact, the parent folder in #babel/runtime has all of the non-ESM things, which I actually probably do want imported! My babel config looks as such:
{
presets: [
[
"#babel/preset-env",
{
modules: 'commonjs',
targets: {
node: "current",
esmodules: false,
},
},
],
"#babel/preset-typescript",
]
}
As you can see, I'm attempting to tell babel via targets.esmodules: false and modules: 'commonjs' to use commonjs. I hoped these entries would tell babel to not expect ESM compatibility! None the less, generated bundles still look like:
...
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(/*! #babel/runtime/helpers/esm/toConsumableArray */ "#babel/runtime/helpers/esm/toConsumableArray"));
My full webpack config is pretty terse as well:
{
entry: serverFilename,
mode: 'development',
output: {
path: path.dirname(serverBuildFilename),
filename: path.basename(serverBuildFilename)
},
target: "node",
externals: [webpackNodeExternals()],
optimization: {
moduleIds: 'named',
minimize: false
},
resolve: {
extensions: ['.ts', '.tsx', '.wasm', '.mjs', '.js', '.json'],
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: babelConfig.presets // see babel config above
}
}
},
],
},
}
I can't tell if I'm missing configuration, if babel isn't respecting my configuration, or <your ideas here>!
All tips appreciated. Thanks!
It took me a while to figure out the solution and this post helps
https://github.com/webpack/webpack/issues/11696
Copied my solution from the issue here:
I ended up using webpack-node-externals in webpack config to sort of bypass this issue
const nodeExternals = require('webpack-node-externals');
// add these to the webpack config.
externals: [
nodeExternals({
whitelist: [/^#babel\/runtime/],
}),
],
This solution creates duplicated babel/runtime file injections and can also be mitigated by https://webpack.js.org/loaders/babel-loader/#babel-is-injecting-helpers-into-each-file-and-bloating-my-code

Node JS Webpack Babel with async

When trying to compile my server-side code, I get the following error:
Module parse failed: (...babel-loader-path)?{"presets":["es2015-node4","es2015"]} (...) Unexpected token (86:6)
You may need an appropriate loader to handle this file type.
This error seems to be caused by an Async function that I am trying to import. Do I need to change my webpack configuration?
My webpack config file:
const webpack = require('webpack');
module.exports = {
target: 'node',
entry: ['./server/index.js', './node_modules/webpack/hot/poll?1000'],
output: {
path: './dist',
filename: 'server.bundle.js',
libraryTarget: 'commonjs',
},
resolve: {
extensions: ['', '.js', '.jsx'],
},
externals: [/^[a-z]/],
module: {
loaders: [{
test: /\.jsx$/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015-node4', 'es2015'],
},
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015-node4', 'es2015'],
},
}
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
devtool: 'source-map',
};
If you are using Webpack to compile your Node code, then that is not a good approach. You should simply use babel-node which is an amazing way to transpile your node code.
For that in your package.json do the following
"scripts": {
"dev": "node_modules/.bin/nodemon --exec babel-node server/index.js",
"prestart": "node_modules/.bin/babel server --out-dir dist",
"start": "node dist/index.js"
},
"devDependencies": {
"#babel/cli": "^7.0.0-beta.40",
"#babel/core": "^7.0.0-beta.40",
"#babel/node": "^7.0.0-beta.40",
"#babel/preset-env": "^7.0.0-beta.40",
"#babel/preset-stage-2": "^7.0.0-beta.40",
"nodemon": "^1.11.0"
}
In your .babelrc file, do the following.
{
"presets": [
"#babel/preset-env",
"#babel/preset-stage-2"
]
}
Then in your project directory create a folder called server and in that folder create a file called index.js which creates your node http server.
For a reference have a look at Babel-Node Documentation
Or have a look at this amazing small tutorial kind of example created by the awesome folks at Babel Example Node Server Using Babel-Node
P.S: In the package.json file the npm run dev watches your code and npm start commands compiles your code ready to be shipped for production.
There seems to be a mis-understanding with regard to the babel preset usage. The preset you want is not the target version of javascript you want to output. For that you need to set target appropriately. Instead you needed the preset that corresponds to the version of javascript you are writing in. The presets are collections of transformers that instruct babel how to deal with specific javascript constructs.
In babel <=6 you need either: es2017 or transform-async-to-generator presets to use the async keyword. After babel 7 the recommendation is to use:
{
"presets": ["#babel/preset-env"]
}
This allows babel to support all modern java-script syntax's that have been finalized. It will then transpile to whatever syntax your target setting indicates. I personally would use a browserslist query in package.json for this so other tools like postcss automatically pick up the same target information.

Grunt + Babel successfully runs but doesn't do anything

I'm rather new to grunt/npm but after reading up the docs. I have made myself a package.json and a Gruntfile.js. Here's my folder structure:
/
|- src
|- myfile.es6
|- anotherfile.es6
|- etc.
|- Gruntfile.js
|- package.json
What I have
Here's my Gruntfile:
module.exports = function(grunt) {
require('load-grunt-tasks')(grunt);
grunt.initConfig({
babel: {
options: {
sourceMap: true,
plugins: ['es2015']
},
dist: {
files: [{
expand: true,
cwd: 'src/',
src: ['*.es6'],
dest: 'dist/',
ext: '.js'
}]
}
}
});
grunt.registerTask('default', ['babel'])
};
And then here's my package.json:
{
"name": "Cheddar",
"version": "0.2.0",
"devDependencies": {
"babel-preset-es2015": "^6.6.0",
"grunt": "^1.0.1",
"grunt-babel": "^6.0.0"
},
"scripts": {
"test": "grunt --verbose"
}
}
What does it do?
I have my src/ folder which contains my source files (*.es6). I want to transpile these to a dist/ directory with grunt.
What I've tried
Then I installed all the dependencies / babel-cli / grunt-cli/ etc. with npm install and npm-update --save
Seems good, so I went ahead and ran grunt:
$ grunt
Running "babel:dist" (babel) task
Done.
$ ls
Gruntfile.js node_modules/ package.json src/
The ls is outputting the exact same thing as before I ran grunt. So nothing is appearing to happen. Where's my output dist? This has been bugging me for the past few hours. I've tried installing babelify, and quite a few other fixes from blogs across the internet but alas, nothing works.
Try using the keyword "presets" instead of "plugins":
babel: {
options: {
sourceMap: true,
presets: ['es2015']
}
...
}
When I use your configuration, grunt seems to error out because it can't find the plugin called "es2015". Everything worked after I made that change.
Try a more literal example from the README like:
grunt.initConfig({
babel: {
options: {
sourceMap: true,
presets: ['es2015']
},
dist: {
files: {
'dist/myfile.js': 'src/myfile.es6'
}
}
} });
After you get that working try specifying *.es6 etc. under files. If you look at the source for the grunt-babel plugin it may be more limited than one would assume.
You can also just use npm scripts and specify the babel command line directly which I feel is simpler than using grunt.

Categories

Resources