Unexpected Identifier {classname} when importing JavaScript Class into another Class - javascript

I'm using Node v10.11.0 and am running this script from Ubuntu 18.04.
My file setup looks like this:
main.js
import Login from './Login.mjs';
class Main {
constructor() {
const login = new Login();
login.login();
}
}
new Main();
Login.mjs
import readline from 'readline';
class Login {
constructor() {
this.username = '';
this.password = '';
this.readline = readline.createInterface({
input: process.stdin,
output: process.stdout
});
}
login() {
this.readline.question('What is your username?', answer => {
this.username = answer;
});
this.readline.question('What is your password?', answer => {
this.password = answer;
});
}
}
export default Login;
I'm calling the main.js with the following command:
node --experimental-modules main.js
This leads to the following error:
(node:7280) ExperimentalWarning: The ESM module loader is experimental.
/home/jrenk/Workspace/bitefight/main.js:1
(function (exports, require, module, __filename, __dirname) { import Login from './Login.mjs';
^^^^^
SyntaxError: Unexpected identifier
at new Script (vm.js:79:7)
at createScript (vm.js:251:10)
at Proxy.runInThisContext (vm.js:303:10)
at Module._compile (internal/modules/cjs/loader.js:657:28)
at Object.Module._extensions..js
(internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at createDynamicModule (internal/modules/esm/translators.js:56:15)
at setExecutor
(internal/modules/esm/create_dynamic_module.js:50:23)
The ^^^^^ belongs under the Login but I can't seem to get it formatted right here in the question.
I also tried to save the Login.mjs as Login.js and calling the main.js without the --experimental-modules but this leads to the exact same error.
This question is similar to this question. As I said above I already tried what is described there but no luck.

Native ES modules (import and export statements) can only be used in .mjs files in Node. In order to use them, entry point should be named main.mjs.
In order to use ES modules in .js files, ES modules should either be transpiled to fall back to require, or used natively with custom ES module loader. Since the latter isn't native Node.js behaviour, it cannot be recommended as a rule of thumb.

Related

SyntaxError: Cannot use import statement outside a module - vue electron builder plugin

I'm having some trouble with vue-cli-electron-builder plugin. I'm trying to use the nodeIntegration as described into the documentations but setting it to true will not give me the ability to use ipcRenderer in my vue compnents. To try fixing the problem I've tried to follow the preload script way but also this without success. Since the copy webpack plugin will not copy the preload.js file when the npm run electron:serve command is running, I've copied the file manually inside the dist_electron folder but I get this error in console when the app is opened
electron/js2c/renderer_init.js:91 Unable to load preload script: /Users/me/Sites/electron-app-demo/desktop-app/dist_electron/preload.js
(function (exports, require, module, __filename, __dirname, process, global, Buffer) { return function (exports, require, module, __filename, __dirname) { import { ipcRenderer } from 'electron';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at new Script (vm.js:88:7)
at createScript (vm.js:261:10)
at Object.runInThisContext (vm.js:309:10)
at wrapSafe (internal/modules/cjs/loader.js:1047:15)
at Module._compile (internal/modules/cjs/loader.js:1108:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1173:10)
at Module.load (internal/modules/cjs/loader.js:992:32)
at Module._load (internal/modules/cjs/loader.js:885:14)
at Function.f._load (electron/js2c/asar_bundle.js:5:12694)
at Object.<anonymous> (electron/js2c/renderer_init.js:91:3099)
Inside the preload.js file I have this code that is the same of the electron builder plugin documentation. The file is in the same folder of the background.js file
import { ipcRenderer } from 'electron';
window.ipcRenderer = ipcRenderer;
And in my vue.config.js file I have this code. The file is placed outside the src folder
const copyPlugin = require('copy-webpack-plugin');
module.exports = {
configureWebpack: {
plugins: [
new copyPlugin([
{ from: 'src/preload.js', to: 'dist_electron/preload.js' }
])
]
},
pluginOptions: {
electronBuilder: {
builderOptions: {
//nodeIntegration: true,
preload: 'src/preload.js'
}
}
}
}
In my vue component I'm importing the ipcRenderer in this way if I use nodeIntegration import { ipcRenderer } from 'electron'; but without success or in this way if I try to use the preload script method window.ipcRenderer.send()
At the moment I have no idea of how to solve this issue and I'm unable to send messages between electron main process and vue. How I can fix this?
I had the same issue - and it seems unfeasibly hard to find out how to resolve it... I went through very similar steps
The root issue is that preload.js isn't being bundled and is therefore missing. Copying it directly into the dist directory is clearly no great answer and as you've discovered doesn't work anyway (the reason for that is that you're copying an unprocessed file...)
Your vue.config.js is incorrect. Move the preload entry outside the builderOptions element. Like so ...
module.exports = {
pluginOptions: {
electronBuilder: {
preload: 'src/preload.js',
as described here

SyntaxError: Cannot use import statment without a module, TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Catch 22

I have been having issues with node js.
Here is the relevant code (app.ts):
const express = require("express");
const auth = require("./service/auth");
import { Request, Response } from "express";
import User from "./model/User";
import con from "./config/db";
const port = 3000;
const app = express();
app.use(express.json());
...
The error I get is:
(node:16524) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
C:\Users\010bo\OneDrive\Documents\GitHub\rpg-backend\app\app.ts:4
import { Request, Response } from "express";
^^^^^^
SyntaxError: Cannot use import statement outside a module
at wrapSafe (internal/modules/cjs/loader.js:1117:16)
at Module._compile (internal/modules/cjs/loader.js:1165:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1221:10)
at Module.load (internal/modules/cjs/loader.js:1050:32)
at Function.Module._load (internal/modules/cjs/loader.js:938:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
So I look for a solution and find:
SyntaxError: Cannot use import statement outside a module
Which tells me to:
Add "type": "module" to the nearest parent package.json
So add "type": "module" to package.json. The output I get now is:
internal/modules/run_main.js:54
internalBinding('errors').triggerUncaughtException(
^
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for C:\Users\010bo\OneDrive\Documents\GitHub\rpg-backend\app\app.ts
[90m at Loader.defaultGetFormat [as _getFormat] (internal/modules/esm/get_format.js:65:15)[39m
[90m at Loader.getFormat (internal/modules/esm/loader.js:98:42)[39m
[90m at Loader.getModuleJob (internal/modules/esm/loader.js:227:31)[39m
[90m at async Loader.import (internal/modules/esm/loader.js:161:17)[39m {
code: [32m'ERR_UNKNOWN_FILE_EXTENSION'[39m
}
So again I go online, look for solution and find: Can't run my Node.js Typescript project TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /app/src/App.ts
Which tells me to:
Remove "type": "module" from package.json
So I think I've found myself in a catch 22 situation. I'm not sure where to go next.
I also tried the other solution in SyntaxError: Cannot use import statement outside a module
Explicitly name files with the .mjs extension. All other files, such as .js will be interpreted as CommonJS, which is the default if type is not defined in package.json.
This didn't work, either giving me the same error or giving me a different syntax error, I think due to the fact that I am using typescript.
Thank you in advance to anyone who can help.
const { Request, Response } = require("express")
Same thing for the other ones.

Why not possible to use ES imports in vue.config.js file with VueJS?

Why aren't ES imports working in vue.config.js file?
In example:
import * as path from 'path';
import * as pjson from './package.json';
module.exports = {
configureWebpack: {
resolve: {
alias: {
'#': path.join(__dirname, '/src'), // Alias # to /src folder for ES/TS imports
},
},
},
pwa: {
name: pjson.title,
assetsVersion: pjson.version,
},
};
Getting error after running npm run lint command (which uses vue-cli-service):
\vue.config.js:1
import * as path from 'path';
SyntaxError: Unexpected token *
at Module._compile (internal/modules/cjs/loader.js:720:23)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
at Module.load (internal/modules/cjs/loader.js:643:32)
at Function.Module._load (internal/modules/cjs/loader.js:556:12)
at Module.require (internal/modules/cjs/loader.js:6
Also import 'path'; is not working either (tried also other syntax variants):
import 'path';
^^^^^^
SyntaxError: Unexpected string
The reason I'm trying to refactor from const path = require('path'); syntax is to avoid this new linter error after ESLint plugins upgrade:
Require statement not part of import
statement. eslint(#typescript-eslint/no-var-requires)
But it seems I still need to append this on top of the file: /* eslint-disable #typescript-eslint/no-var-requires */
The file vue.config.js is loaded by #vue/cli-shared-utils/lib/module.js via CommonJS require. Because of that, it expects vue.config.js to be CommonJS, too.
There are a few schemes you could employ to overcome this built-in limitation such as using vue.config.js to
require('#babel/register');
then require another file like vue.config.mjs where your ESM-based code resides.
But given this is only a config file that usually doesn't have a lot of code, it may be better not to fight city hall and instead use CommonJS.

Testing AMD modules with tape/ES6 unit tests?

I have a web app using:
ES5
RequireJS
Underscore
Backbone
jQuery
I have tried setting up a new unit test suite using:
ES6
Tape
Babel6
My AMD module app/util/stringUtil.js:
define([], function() {
'use strict';
return {
isBlank: function(str) {
return _.isUndefined(str) || _.isNull(str) || _.isString(str) && str.trim().length === 0;
}
};
});
My unit test in tapeTest.js:
import test from 'tape';
import sortUtil from 'app/util/stringUtil';
test('Testing stringUtil', (assert) => {
assert.ok(stringUtil.isBlank(' ')),
'Should be blank');
assert.end();
});
My .babelrc:
{
"presets": ["es2015"]
}
I run the test with tape:
tape -r babel-register tapeTest.js
I get the following error:
app/util/stringUtil.js:1
(function (exports, require, module, __filename, __dirname) { define([], function () {
^
ReferenceError: define is not defined
at Object.<anonymous> (stringUtil.js:1:23)
at Module._compile (module.js:434:26)
at loader (node_modules/babel-register/lib/node.js:126:5)
at Object.require.extensions.(anonymous function) [as .js] (node_modules/babel-register/lib/node.js:136:7)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (tapeTest.js:7:17)
at Module._compile (module.js:434:26)
I'm guessing tape doesn't recognize AMD modules? Can I fix this somehow? Maybe transpile AMD modules to CommonJS modules or something?
You can load AMD modules inside node with requirejs :_)
Read here: http://requirejs.org/docs/node.html
You have to import require and do a little config, something like this:
'use strict';
const test = require('tape');
const requirejs = require('requirejs');
requirejs.config({
baseUrl: __dirname,
nodeRequire: require
});
test('Test something', function (assert) {
requirejs(['app/util/stringUtil'], function (stringUtil) {
assert.ok(stringUtil.isBlank(' '), 'Should be blank');
assert.end();
});
});
I solved it by using karma, webpack and phantomjs launcher:
karma
karma-webpack
karma-phantomjs-launcher
karma-tap
tape
Webpack transpiles the ES6 unit tests to ES5 modules and karma launches and runs the tests in a phantomjs browser.

Gulp Node.js Istanbul Isparta

I'm trying to get unit tests coverage with Istanbul and Isparta, and I'm having some trouble.
Actually, here's my gulp file tasks:
gulp.task('pre-test', ['default'], function() {
return gulp.src('src/app/**/*.js')
.pipe(plumber())
.pipe(istanbul({
instrumenter: isparta.Instrumenter,
includeUntested: true
}))
.pipe(istanbul.hookRequire());
});
gulp.task('test', ['pre-test'], function() {
return gulp.src('src/test/**/*.js')
.pipe(mocha({reporter: 'spec'}))
.pipe(istanbul.writeReports({}));
});
When I start the gulp "test" task, I have the following errors:
[08:34:17] Plumber found unhandled error:
Error in plugin 'gulp-istanbul'
Message:
Unable to parse C:\projects\nodejs\mon-notaire\src\app\core\logger\concrete\ConsoleLogger.js
Line 1: Unexpected token
[08:34:17] Finished 'pre-test' after 2.11 s
[08:34:17] Starting 'test'...
stream.js:94
throw er; // Unhandled stream error in pipe.
^
C:\projects\nodejs\mon-notaire\src\test\core\TestConfReader.js:1
(function (exports, require, module, __filename, __dirname) { import ConfReade
^^^^^^
SyntaxError: Unexpected reserved word
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Object.Module._extensions.(anonymous function) [as .js] (C:\projects\nodejs\mon-notaire\node_modules\gulp-istanbul\node_modules\istanbul\lib\hook.js:109:37)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at C:\projects\nodejs\mon-notaire\node_modules\mocha\lib\mocha.js:192:27
at Array.forEach (native)
npm ERR! Test failed. See above for more details.
How can I prevent these errors from occurring?
Have you set up .babelrc?
If you're using the latest version of isparta, which depends on babel v6, then you need to set up .babelrc like the following. ( You also need to do npm install --save-dev babel-preset-es2015 )
{
"presets": [
"es2015"
]
}
From gulp-istanbul github page.
var isparta = require('isparta');
var istanbul = require('gulp-istanbul');
gulp.src('lib/**.js')
.pipe(istanbul({
// supports es6
instrumenter: isparta.Instrumenter
}));
This line :
Message:
Unable to parse C:\projects\nodejs\mon-notaire\src\app\core\logger\concrete\ConsoleLogger.js
Means that there is a problem in your code in ConsoleLogger.js , so you might want to check that file out.
This Line :
C:\projects\nodejs\mon-notaire\src\test\core\TestConfReader.js:1
(function (exports, require, module, __filename, __dirname) { import ConfReade
^^^^^^
SyntaxError: Unexpected reserved word
Suggests that you are using ES6, but your gulp task is not transpiling it to ES5 before running it, which is why you are getting the error.
I have made a yeoman generator which creates a project for exactly this purpose (writing nodeJs projects in ES6) and includes code coverage using istanbul with source code mapping. You might want to take a look at that.
Otherwise, here is my working gulpfile from that generator.
I use istanbul, along with a module called remap-istanbul.
The error message indicates that you are using ES6, but the gulp-istanbul doesn't support it by default.
Of course, you can write your functions to compile the ES6 codes, but considering you are using gulp in this case, IMHO the simplest way you can do is to use gulp-babel-istanbul instead of gulp-istanbul, no need to change your code attached above at all.
import istanbul from 'gulp-babel-istanbul'
And the rest of the code remains the same.

Categories

Resources