VueJS error on IE11 - SCRIPT1004: Expected ';' - javascript

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

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"
},
...

Why Jest failing on node-fetch giving syntax error on import

I'm trying to understand how to fix the following error using Jest in my unit tests in NodeJS.
The test run with this command "test": "NODE_ENV=test jest spec/* -i --coverage --passWithNoTests",
I'm also using babel and this is my config
{
"presets": [["#babel/env", { "targets": { "node": "current" } }]],
"plugins": [
"#babel/plugin-syntax-dynamic-import",
["babel-plugin-inline-import", { "extensions": [".gql"] }],
["#babel/plugin-proposal-decorators", { "legacy": true }]
]
}
In package.json I have this
"jest": {
"verbose": true,
"collectCoverageFrom": [
"spec/**/*.js"
]
},
I tried several guides online but cannot find a solution to this
You've got Jest successfully configured to transform your code, but it is not transforming modules that you're importing—in this case node-fetch, which has the import keyword in its source code (as seen in your error). This is because, by default, Jest is configured not to transform files in node_modules:
transformIgnorePatterns [array]
Default: ["/node_modules/", "\.pnp\.[^\/]+$"]
An array of regexp pattern strings that are matched against all source file paths before transformation. If the file path matches any of the patterns, it will not be transformed.
You can set transformIgnorePatterns to exclude certain packages in node_modules with a jest.config.js like this:
const esModules = [
'node-fetch',
'data-uri-to-buffer',
'fetch-blob',
'formdata-polyfill',
].join('|');
module.exports = {
transformIgnorePatterns: [
`/node_modules/(?!${esModules})`,
'\\.pnp\\.[^\\/]+$',
],
};
(see https://github.com/nrwl/nx/issues/812#issuecomment-429420861)
If you have .babelrc try to rename it to babel.config.js
Source:
https://babeljs.io/docs/en/configuration#whats-your-use-case
but also this (there's more in the discussion)
Jest won't transform the module - SyntaxError: Cannot use import statement outside a module

vite/rollup with #rollup/plugin-babel does not strip template literal backticks when set to ie >= 11

Attempting to use Vite in library mode to compile an ES6 .js files down to a bundled ES5 .js file that will run in Internet Explorer 11. In my actual app there are several files that use ESM import/export, however I have verified that I can reproduce the problem with a single, simplified example file. Which I will include below.
Here is my configuration:
//vite.config.js
const path = require('path');
const { defineConfig } = require('vite');
import { babel } from '#rollup/plugin-babel';
module.exports = defineConfig({
esbuild: false,
plugins: [
babel({
babelHelpers: 'bundled',
presets: [['#babel/preset-env', { targets: { browsers: 'defaults, ie >= 11' } }]],
}),
],
build: {
outDir: 'javascript',
lib: {
entry: path.resolve(__dirname, 'js-src/index.js'),
name: 'MyLib',
fileName: (format) => 'my-lib.js',
},
},
});
Test File:
const aWord = 'World';
const multiLineString = `
Hello ${aWord}
`;
console.log(multiLineString);
Resulting output file:
(function(n){typeof define=="function"&&define.amd?define(n):n()})(function(){"use strict";var n=`
Hello `.concat(aWord,`
`);console.log(n)});
Notice how the transpiled code does down-shift to ES5 (see var instead of const) but it does not remove the template literal backticks and convert them to some other type of string that is safe for Internet Explorer 11. It only happens on multi-line template literal strings though. A single-line template literal will get changed to a string with " characters.
Looking for a solution to force babel to remove these backtick characters and convert them a supported type of string (that preserves the linebreaks as well)
I found the culprit.
It is not Babel but Esbuild.
After Babel has done a great job on transpiling everything properly (I checked, it does) the optimization kicks in and Esbuild (by default) "optimizes" those newly arrived linebreaks "\n" back into much slimmer (char wise) multiline strings.
I see that you tried to disable Esbuild with esbuild = false but maybe this wasn't the correct config option "back then" (in Nov21) to stop Esbuild from messing up your results.
In order to stop Esbuild from re-transpiling strings with line breaks back multiline strings you have two options
disable minification: build.minify = false
or set build.target = 'ie11'
Once build.target is set to ie11 the build process will start complaining that Esbuild is not ready to transpile quite some parts of your code to IE11 specification. I assume that this is because Esbuild runs before the plugins are ran and later again for the final optimization.
So using #vite/babel is not an option anymore, the new Babel-way goes via #rollup/plugin-babel.
The following is my working vite.config.js or at least the important parts to it:
// vite.config.js
import { defineConfig } from 'vite'
import { getBabelOutputPlugin } from '#rollup/plugin-babel'
export default defineConfig({
build: {
target: 'ie11',
lib: {
/* your vite lib mode params */
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: [],
output: {
plugins: [
/**
* Running Babel on the generated code:
* https://github.com/rollup/plugins/blob/master/packages/babel/README.md#running-babel-on-the-generated-code
*
* Transforming ES6+ syntax to ES5 is not supported yet, there are two ways to do:
* https://github.com/evanw/esbuild/issues/1010#issuecomment-803865232
* We choose to run Babel on the output files after esbuild.
*
* #vitejs/plugin-legacy does not support library mode:
* https://github.com/vitejs/vite/issues/1639
*/
getBabelOutputPlugin({
allowAllFormats: true,
presets: [
[
'#babel/preset-env',
{
targets: '> 0.25%, not dead, IE 11',
useBuiltIns: false, // Default:false
// // https://babeljs.io/docs/en/babel-preset-env#modules
modules: false
},
]
]
}),
]
},
plugins: [...]
}
}
})
You can use #vitejs/plugin-legacy to support IE 11 in Vite.
I test with a simple Vite project with vanilla JavaScript and add the test file code like yours. I first run npm i -D #vitejs/plugin-legacy, then use a vite.config.js file like below:
import legacy from '#vitejs/plugin-legacy'
export default {
plugins: [
legacy({
targets: ['ie >= 11'],
additionalLegacyPolyfills: ['regenerator-runtime/runtime']
})
]
}
Then I run npm run build, the generated js file in dist folder is like below which supports IE 11:
System.register([],(function(){"use strict";return{execute:function(){var e="\n Hello ".concat("World","\n");console.log(e)}}}));

Sourcemaps breaks for console.log in node_modules in webpack and babel build

I'm trying to enable sourcemaps for my Babel 7.7 and Webpack 4.41 built code.
The sourcemaps work fine except for console statements that originate from code in node_modules. These statements are mostly dev hints, warnings for when we do something wrong. For console statements in our own source code the sourcemaps work, they also work if an error occurs in the 3rd party lib.
When a dependency console.logs the trace looks like this:
Warning: a promise was rejected with a non-error: [object String]
at eval (webpack-internal:///./src/app/bootstrap/bootstrap.js:66:13)
From previous event:
at _callee$ (webpack-internal:///./src/app/bootstrap/bootstrap.js:65:140)
at tryCatch (webpack-internal:///../node_modules/regenerator-runtime/runtime.js:45:40)
at Generator.invoke [as _invoke] (webpack-internal:///../node_modules/regenerator-runtime/runtime.js:271:22)
at Generator.prototype.<computed> [as next] (webpack-internal:///../node_modules/regenerator-runtime/runtime.js:97:21)
When inspecting bootstrap.js in the browser I don't exactly get the build code, a sourcemap is still applied, but I also don't get the output from babel, even less the original code. It's some state in between.
I've created a simple repo where the issue is reproduced, to try to solve it in a controlled manner: https://github.com/pstenstrm/webpack-sourcemap-test
Object(react_loadable__WEBPACK_IMPORTED_MODULE_9__["preloadReady"])().then(function _callee() {
return _Users_path_to_proj_node_modules_babel_runtime_corejs3_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.async(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return _Users_path_to_proj_node_modules_babel_runtime_corejs3_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.awrap(new bluebird__WEBPACK_IMPORTED_MODULE_1___default.a(function (a, reject) {
reject('asdas');
}));
My babel config looks like this:
{
"presets": [
[
"#babel/preset-env",
{
targets: {
browsers: "last 2 versions"
}
}
]
],
"plugins": [
[
"#babel/plugin-transform-runtime",
{
"corejs": 3,
"proposals": true,
"absoluteRuntime": true
}
]
]
}
In webpack the setup looks like this:
const path = require('path');
module.exports = {
entry: ['./src/index.js'],
mode: 'development',
devtool: 'eval-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [{
test: /\.js$/,
exclude: [/node_modules/],
use: 'babel-loader?sourceMap&cacheDirectory'
}]
},
};
I've tested all options for https://webpack.js.org/configuration/devtool/, while some options made it marginally worse no option made it better.
I've also tried to configure SourceMapDevToolPlugin and EvalSourceMapDevToolPlugin to solve the issue but again no improvement. I might be missing something but I don't know what it might be.
Is this expected, is console.log in node_modules simply not supported, or is there a setting I'm missing?

Rollup with d3 namedExports issue

I have a package I am making which uses d3. Of course, in my rollup.config.js file I declare d3 as both an external and global package:
let config = {
...,
output: {
external: ['d3'],
globals: {d3:'d3'},
...,
},
...
}
and I might have a function in a file somewhere like:
import * as d3 from 'd3'
...
export function someFunc(arg1, arg2) {
d3.select(arg1)
d3.min(arg2)
}
...
and when I bundle my code with rollup -c I get the nice warning that
src/modules/some-file.js
selection is not exported by node_modules/d3/dist/d3.node.js
so I go back to my rollup.config.js file and add the following:
// inside config
plugins: [
...,
commonjs({
...,
namedExports: {
'node_modules/d3/dist/d3.node.js': [
'selection', 'min',
]
},
...,
})
...,
]
and now my bundle has no warnings or complaints... but when I go to use my bundled code, I get errors like:
TypeError: d3_node_1 is null
TypeError: d3_node_2 is null
where d3_node_1 appears where I have d3.select in my code and d3_node_2 appears where d3.min is.
How do I get around this?
You probably have to use the rollup-plugin-node-resolve to use third party modules from node_modules
adding 'module' to mainFields seemed to solve it
nodeResolve({
mainFields: [
'module',
'main', 'jsnext'
]
}),

Categories