How to configure Nuxt 2.8 to generate ES5-compatible code? - javascript

By default Nuxt generates (by 'nuxt generate') code, which is incompatible with the ES5-standard.
How can I correct it?
What exactly needs to be written in nuxt.config.js so that everything is correct? I know that these are some presets for Babel, but I don't know which ones
Thank you!
upd.: Nuxt generated code with 'const' instead 'var' - it is NOT 'ES5 compatible code', isn't it?

I believe Nuxt generates ES5 compatible code by default, but if you need to change browser target you can use the following:
build: {
babel: {
presets: [
[
require.resolve("#nuxt/babel-preset-app"),
{
browsers: ["IE 11", "last 2 version"]
}
]
];
}
}
For what you can use in browsers property, refer to browserslist documentation.

Problem was in Quasar.js connected as Nuxt-plugin (Node-CLI module).
This resolve it:
in nuxt.config.js:
build: {
transpile: [
'quasar',
],
}

Related

Module parse failed: Unexpected token ? Optional chaining not recognised in threejs svgloader.js [duplicate]

Project setup:
Vuejs 3
Webpack 4
Babel
TS
We created the project using vue-cli and add the dependency to the library.
We then imported a project (Vue Currency Input v2.0.0) that uses optional chaining. But we get the following error while executing the serve script:
error in ./node_modules/vue-currency-input/dist/index.esm.js
Module parse failed: Unexpected token (265:36)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| getMinValue() {
| let min = this.toFloat(-Number.MAX_SAFE_INTEGER);
> if (this.options.valueRange?.min !== undefined) {
| min = Math.max(this.options.valueRange?.min, this.toFloat(-Number.MAX_SAFE_INTEGER));
| }
I read that Webpack 4 doesn't support optional chaining by default. So, we added the Babel plugin for optional chaining. This is our babel.config.js file:
module.exports = {
presets: ["#vue/cli-plugin-babel/preset"],
plugins: ["#babel/plugin-proposal-optional-chaining"],
};
(But, if I am correct, this plugin is now enable by default in the babel-preset. So this modification might be useless ^^)
One thing that I don't understand is that we can use optional chaining in the .vue files.
I created a SandBox with all the files: SandBox
How could I solve this error?
I was able to overcome this issue using #babel/plugin-proposal-optional-chaining, but for me the only way I could get Webpack to use the Babel plugin was to shove the babel-loader configuration through the Webpack options in vue.config.js. Here is a minimal vue.config.js:
const path = require('path');
module.exports = {
chainWebpack: config => {
config.module
.rule('supportChaining')
.test(/\.js$/)
.include
.add(path.resolve('node_modules/PROBLEM_MODULE'))
.end()
.use('babel-loader')
.loader('babel-loader')
.tap(options => ({ ...options,
plugins : ['#babel/plugin-proposal-optional-chaining']
}))
.end()
}
};
NB replace "PROBLEM_MODULE" in the above with the module where you have the problem.
Surprisingly I did not need to install #babel/plugin-proposal-optional-chaining with NPM. I did a go/no-go test with an app scaffolded with #vue/cli 4.5.13, in my case without typescript. I imported the NPM module that has been causing my grief (#vime/vue-next 5.0.31 BTW), ran the serve script and got the Unexpected token error on a line containing optional chaining. I then plunked the above vue.config.js into the project root and ran the serve script again, this time with no errors.
My point is it appears this problem can be addressed without polluting one's development environment very much.
The Vue forums are in denial about this problem, claiming Vue 3 supports optional chaining. Apparently not, however, in node modules. A post in this thread by atflick on 2/26/2021 was a big help.
Had same issue with Vue 2 without typescript.
To fix this you need to force babel preset to include optional chaining rule:
presets: [
[
'#vue/cli-plugin-babel/preset',
{
include: ['#babel/plugin-proposal-optional-chaining'],
},
],
],
Can also be achieved by setting old browser target in browserslist config.
Most importantly, you need to add your failing module to transpileDependencies in vue.config.js:
module.exports = {
...
transpileDependencies: ['vue-currency-input],
}
This is required, because babel by default will exclude all node_modules from transpilation (mentioned in vue cli docs), thus no configured plugins will be applied.
I had a similar problem. I'm using nuxt but my .babelrc file looks like the below, and got it working for me.
{
"presets": [
["#babel/preset-env"]
],
"plugins":[
["#babel/plugin-transform-runtime",
{
"regenerator": true
}
]
],
"env": {
"test": {
"plugins": [
["transform-regenerator", {
"regenerator": true
}],
"#babel/plugin-transform-runtime"
],
"presets": [
["#babel/preset-env", {
"useBuiltIns": false
}]
]
}
}
}
I managed to fix the solution by adding these lines to package.json:
...
"scripts": {
"preinstall": "npx npm-force-resolutions",
...
},
"resolutions": {
"acorn": "8.0.1"
},
...

.globals is not a valid Plugin property

I want to integrate the QR code scanner feature in my react-native-based applications.
so I am installing the react-native-vision-camera package.
According to documentation, I have to add globals __scanQRCodes inside babel.config.js
globals: ['__scanQRCodes']
But after adding globals __scanQRCodes inside babel.config.js.
I got BABEL TRANSFORM ERROR
.globals is not a valid Plugin property
we need to define the array as shown in the image below, you miss the square brackets like this:
plugins: [
[
'react-native-reanimated/plugin',
{ globals: ['__scanQRCodes'] }
]
]
see this image for proper understand
We need to do this 2 modifications:
plugins: [
[
'react-native-reanimated/plugin',
{ globals: ['__scanCodes'] },
],
]
And finally:
npx react-native start --reset-cache

What is best practice for `#babel/preset-env` + `useBuiltIns` + `#babel/runtime` + `browserslistrc`

I get different output for different configurations of #babel/preset-env with useBuiltIns used in combination with #babel/transform-runtime. I've read the documentation, but haven't been able to figure out what the best practice should be.
For example, #babel/preset-env with useBuiltIns will add a polyfill for string.replace when my targeted list of browsers includes Edge 18.
But when I use #babel/transform-runtime instead, that polyfill doesn't get added.
So, starting out with this question:
Does `string.replace` need to be polyfilled for Edge 18?
I checked caniuse.com which shows it as fully supported - which would mean no polyfills are required.
However, according to Manuel Beaudru's blog post core-js#3, babel and a look into the future
caniuse, mdn and compat-table are good educational resources but
aren't really meant to be used as data sources for developer tools:
only the compat-table contains a good set of ES-related data and it
is used by #babel/preset-env, but it has some limitations
And further:
For this reason, I created the core-js-compat package: it provides
data about the necessity of core-js modules for different target
engines. When using core-js#3, #babel/preset-env will use that new
package instead of compat-table.
So I passed my target browsers to core-js-compat and it output all the polfills required. As you can see in the image below, quite a few string methods need to be polyfilled, mostly to support Edge 18.
So far, so good. It looks like string.replace does need to be polyfilled for Edge 18.
Babel config
First approach: #babel/preset-env and useBuiltIns: 'usage'
When I use useBuiltIns: 'usage' to bring in per-file polyfills from core-js:
// babel.config.js
presets: [
[
'#babel/preset-env',
{
debug: false,
bugfixes: true,
useBuiltIns: 'usage',
corejs: { version: "3.6", proposals: true }
}
],
'#babel/preset-flow',
'#babel/preset-react'
],
When debug: true, Babel says it will add the following polyfills to my PriceColumn.js file:
// Console output
[/price-column/PriceColumn.js] Added following core-js polyfills:
es.string.replace { "edge":"17", "firefox":"71", "ios":"12", "safari":"12" }
es.string.split { "edge":"17" }
web.dom-collections.iterator { "edge":"17", "ios":"12", "safari":"12" }
One difference is that it says es.string.replace is to target edge: 17, not edge: 18 as we see in the output from core-js-compat above - might be something I've done, but that's fine for now.
The additions that Babel adds to the top of the transpiled PriceColumn.js file:
// PriceColumn.js
"use strict";
require("core-js/modules/es.string.replace");
require("core-js/modules/es.string.split");
require("core-js/modules/web.dom-collections.iterator");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Again, so far so good.
Second approach: #babel/runtime and #babel/transform-runtime
According to the core-js documentation:
#babel/runtime with corejs: 3 option simplifies work with
core-js-pure. It automatically replaces usage of modern features
from JS standard library to imports from the version of core-js
without global namespace pollution
Sounds great - let's try it out!
Commenting out useBuiltIns and adding #babel/transform-runtime plugin config:
// babel.config.js
presets: [
[
'#babel/preset-env',
{
debug: true,
// bugfixes: true,
// useBuiltIns: 'usage',
// corejs: { version: '3.6', proposals: true }
}
],
'#babel/preset-flow',
'#babel/preset-react'
],
plugins: [
[
'#babel/transform-runtime',
{
corejs: { version: 3, proposals: true },
version: '^7.8.3'
}
]
],
In the console output, I see:
Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set.
Checking what was added to the top of the file:
// PriceColumn.js
"use strict";
var _interopRequireDefault = require("#babel/runtime-corejs3/helpers/interopRequireDefault");
var _Object$defineProperty = require("#babel/runtime-corejs3/core-js/object/define-property");
_Object$defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _objectSpread2 = _interopRequireDefault(require("#babel/runtime-corejs3/helpers/objectSpread2"));
var _map = _interopRequireDefault(require("#babel/runtime-corejs3/core-js/instance/map"));
So, different helpers were added - but no sign of the es.string.* polyfills. Are they no longer required? Are they already brought in by the 'helpers'? It doesn't look like object spread and array map would have anything to do with polyfilling string instance methods, so I think not.
Finally
My last attempt was to combine both approaches - and to follow the recommendations:
a) Set corejs for #babel/preset-env:
// babel.config.js
presets: [
[
'#babel/preset-env',
{
debug: true,
// bugfixes: true,
useBuiltIns: 'usage',
corejs: { version: '3.6', proposals: true }
}
],
'#babel/preset-flow',
'#babel/preset-react'
],
plugins: [
[
'#babel/transform-runtime',
{
// corejs: { version: 3, proposals: true },
version: '^7.8.3'
}
]
]
and this is the output:
// PriceColumn.js
"use strict";
var _interopRequireDefault = require("#babel/runtime/helpers/interopRequireDefault");
require("core-js/modules/es.string.replace");
require("core-js/modules/es.string.split");
require("core-js/modules/web.dom-collections.iterator");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _objectSpread2 = _interopRequireDefault(require("#babel/runtime/helpers/objectSpread2"));
b) Set corejs for #babel/transform-runtime:
same as second approach (see above)
Comparing the output for the different approaches
Using just useBuiltIns:
Brings in the required string polyfills, but pollutes the global namespace.
Using just #babel/runtime-transform:
Doesn't bring in any string polyfills, but brings in other helpers/polyfills ??, for Array map and Object spread
Using combination of both useBuiltIns and #babel/transform-runtime:
Brings in the required string polyfills, but pollutes the global namespace.
Also brings in Object spread polyfill (but not the Array map polyfill)
Imports from #babel/runtime/helpers/objectSpread2, not #babel/runtime-corejs3/helpers/objectSpread2 (runtime vs runtime-corejs3) - could be the reason that Array map polyfill was not brought in??)
Question
Which - if any - of these is the correct approach?
I'm guessing the #babel/preset-env with useBuiltIns is the best because it brings in the polyfills.
What are the drawbacks to polluting the global namespace? Is this an issue for libraries only?
In combination with #babel/transform-runtime, we also get a polyfill for object spread (even though #babel-preset-env has corejs: { version: '3.6', proposals: true } which should polyfill proposals, so I'm not sure why it doesn't get brought in there without having to use the #babel/transform-runtime plugin too)
Do we need the Array#map polyfill?
Suggested by https://www.jmarkoski.com/understanding-babel-preset-env-and-transform-runtime:
App: If you are authoring an app, use import 'core-js at the top of your app with useBuiltIns set to entry and #babel/transform-runtime only for helpers (#babel/runtime as dependency). This way you pollute the global environment but you don't care, its your app. You will have the benefit of helpers aliased to #babel/runtime and polyfills included at the top of your app. This way you also don't need to process node_modules (except when a dependency uses a syntax that has to be transpiled) because if some dependency used a feature that needs a polyfill, you already included that polyfill at the top of your app.
Library: If you are authoring a library, use only #babel/transform-runtime with corejs option plus #babel/runtime-corejs3 as dependency, and #babel/preset-env for syntax transpilation with useBuiltIns: false. Also I would transpile packages I would use from node_modules. For this you will need to set the absoluteRuntime option (https://babeljs.io/docs/en/babel-plugin-transform-runtime#absoluteruntime) to resolve the runtime dependency from a single place, because #babel/transform-runtime imports from #babel/runtime-corejs3 directly, but that only works if #babel/runtime-corejs3 is in the node_modules of the file that is being compiled.
More Info:
https://github.com/zloirock/core-js/issues/848
https://github.com/zloirock/core-js/issues/833
https://babeljs.io/docs/en/babel-plugin-transform-runtime

VueJS error on IE11 - SCRIPT1004: Expected ';'

IE11 - ERROR: SCRIPT1004: Expected ';'
Hi! My website works on every browser except IE. My babel.config.js file:
module.exports = {
presets: [
['#vue/app', {
polyfills: [
'es.promise',
'es.symbol',
'es6.array.iterator'
]
}]
],
"plugins": [
"#babel/plugin-transform-shorthand-properties",
"#babel/plugin-proposal-object-rest-spread",
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
]
]
}
---> Console screenshot
---> Debugger screenshot
Your debugger screenshot shows the error is from the native-toast package. That package's GitHub shows an unresolved issue, in which a for ... of loop is used. IE does not know how to interpret it, which is a common cause of the Vue IE SCRIPT1004 error (which is just a missing semicolon).
You can tell Vue CLI to transpile the entire native-toast dependency package, which is something it does not do by default. In your vue.config.js (not Babel):
module.exports = {
transpileDependencies: [
'native-toast'
]
}
(Note: transpileDependencies is an array of package names [or RegExp])
Apparently, in some cases you may also need this in your babel.config.js (try without it first):
module.exports = {
"presets": [
'#babel/preset-env'
],
}
Reference:
Vue CLI transpileDependencies
Vue CLI polyfills guide
Vue Forum transpileDependencies example

How to remove global "use strict" added by babel

I'm using function form of "use strict" and don't want global form which Babel adds after transpilation. The problem is I'm using some libraries that aren't using "use strict" mode and it might throw error after scripts are concatenated
As it has already been mentioned for Babel 6, it's the transform-es2015-modules-commonjs preset which adds strict mode.
In case you want to use the whole es2015 preset without module transformations, put this in your .babelrc file:
{
"presets": [
["es2015", { "modules": false }]
]
}
This will disable modules and strict mode, while keeping all other es2015 transformations enabled.
Babel 5
You'd blacklist "useStrict". For instance here's an example in a Gruntfile:
babel: {
options: {
blacklist: ["useStrict"],
// ...
},
// ...
}
Babel 6
Since Babel 6 is fully opt-in for plugins now, instead of blacklisting useStrict, you just don't include the strict-mode plugin. If you're using a preset that includes it, I think you'll have to create your own that includes all the others, but not that one.
There's now a babel plugin that you can add to your config that will remove strict mode: babel-plugin-transform-remove-strict-mode. It's a little ugly in that the "use strict" gets added and then removed, but it makes the config much nicer.
Docs are in the GitHub repo:
https://github.com/genify/babel-plugin-transform-remove-strict-mode
Your .babelrc ends up looking like this:
{
"presets": ["env"],
"plugins": ["transform-remove-strict-mode"]
}
I also came accross this rather ridiculous limitation that you cannot disable or overwrite settings from an existing preset, and have resorted to using this preset instead: https://www.npmjs.com/package/babel-preset-es2015-without-strict
plugins: [
[
require("#babel/plugin-transform-modules-commonjs"),
{
strictMode: false
}
],
]
You can tell babel that your code is a script with:
sourceType: "script"
in your babel config file. This will not add use strict. See sourceType option docs
Source: https://github.com/babel/babel/issues/7910#issuecomment-388517631
Babel 6 + es2015
We can disabled babel-plugin-transform-es2015-modules-commonjs to require babel-plugin-transform-strict-mode.
So comment the following code in node_modules/babel-plugin-transform-es2015-modules-commonjs/lib/index.js at 151 line
//inherits: require("babel-plugin-transform-strict-mode"),
just change .babelrc solution
if you don't want to change any npm modules, you can use .babelrc ignore like this
{
"presets": ["es2015"],
"ignore": [
"./src/js/directive/datePicker.js"
]
}
ignore that file, it works for me!
the ignored file that can't use 'use strict' is old code, and do not need to use babel to transform it!
Personally, I use the gulp-iife plugin and I wrap IIFEs around all my files. I noticed that the babel plugin (using preset es2015) adds a global "use strict" as well. I run my post babel code through the iife stream plugin again so it nullifies what babel did.
gulp.task("build-js-source-dev", function () {
return gulp.src(jsSourceGlob)
.pipe(iife())
.pipe(plumber())
.pipe(babel({ presets: ["es2015"] }))// compile ES6 to ES5
.pipe(plumber.stop())
.pipe(iife()) // because babel preset "es2015" adds a global "use strict"; which we dont want
.pipe(concat(jsDistFile)) // concat to single file
.pipe(gulp.dest("public_dist"))
});
This is not grammatically correct, but will basically work for both Babel 5 and 6 without having to install a module that removes another module.
code.replace(/^"use strict";$/, '')
Since babel 6 you can install firstly babel-cli (if you want to use Babel from the CLI ) or babel-core (to use the Node API). This package does not include modules.
npm install --global babel-cli
# or
npm install --save-dev babel-core
Then install modules that you need. So do not install module for 'strict mode' in your case.
npm install --save-dev babel-plugin-transform-es2015-arrow-functions
And add installed modules in .babelrc file like this:
{
"plugins": ["transform-es2015-arrow-functions"]
}
See details here: https://babeljs.io/blog/2015/10/31/setting-up-babel-6
For babel 6 instead of monkey patching the preset and/or forking it and publishing it, you can also just wrap the original plugin and set the strict option to false.
Something along those lines should do the trick:
const es2015preset = require('babel-preset-es2015');
const commonjsPlugin = require('babel-plugin-transform-es2015-modules-commonjs');
es2015preset.plugins.forEach(function(plugin) {
if (plugin.length && plugin[0] === commonjsPlugin) {
plugin[1].strict = false;
}
});
module.exports = es2015preset;
Please use "es2015-without-strict" instead of "es2015". Don't forget you need to have package "babel-preset-es2015-without-strict" installed. I know it's not expected default behavior of Babel, please take into account the project is not mature yet.
I just made a script that runs in the Node and removes "use strict"; in the selected file.
file: script.js:
let fs = require('fs');
let file = 'custom/path/index.js';
let data = fs.readFileSync(file, 'utf8');
let regex = new RegExp('"use\\s+strict";');
if (data.match(regex)){
let data2 = data.replace(regex, '');
fs.writeFileSync(file, data2);
console.log('use strict mode removed ...');
}
else {
console.log('use strict mode is missing .');
}
node ./script.js
if you are using https://babeljs.io/repl (v7.8.6 as of this writing), you can remove "use strict"; by selecting Source Type -> Module.
Using plugins or disabling modules and strict mode as suggested in the #rcode's answer didn't work for me.
But, changing the target from es2015|es6 to es5 in tsconfig.json file as suggested by #andrefarzart in this GitHub answer fixed the issue.
// tsconfig.json file
{
// ...
"compilerOptions": {
// ...
"target": "es5", // instead of "es2015"
}

Categories