We're using async/await for our Meteor project. This syntax is everywhere in our resolvers.js. Everything has been working fine until we've upgraded to Node 6.7. Now it shows this error every time we try to build it:
"The keyword 'await' is reserved (53:24)"
Does anyone know how to solve this?
Here is the content of my .babelrc file:
{
"presets": ["es2015", "stage-2", "react"],
"plugins": ["react-require", "babel-root-slash-import"]
}
Just in case anyone else searches for this same issue, in my case it was user error, me. I forgot to put the async keyword before the function name.
Okay, I found out a solution to my own problem. I just excluded the .babelrc when doing a Meteor build since Meteor already has a package that supports ES6 syntax. I didn't totally remove the .babelrc because I will be needing it on tests and when running the Storybook which does not trigger a Meteor build.
Await alone is invalid syntax. await needs to be called inside an async function like:
var aFunction = async function() {
let aResponse = await get('aValue');
}
Related
I've just started using eslint. I initialized it and started fixing problems it pointed out.
One problem, however, it shouldn't complain about:
const data = fs.readFileSync(path.join(__dirname, _FILENAME));
The error is:
error '__dirname' is not defined
I did some searching and found that when you add --experimental to the node command that __dirname is not defined. This, however, isn't the case for me. I'm not running node with the --experimental flag.
See these questions:
Alternative for __dirname in Node.js when using ES6 modules
__dirname is not defined in nodejs
This is happening because ESLint does not know that your code is supposed to be used in Node.js: __dirname is not defined in browsers and also not defined in ES modules. To tell ESLint that your code will run in Node.js as a CommonJS module, open your ESLint config and set node: true in the env section. If you are using .eslintrc.json:
{
"env": {
"node": true
}
}
There are also other ways to specify environments, they are explained in the related documentation.
I ran into the same. Adding this to .eslintrc.json fixed it for me:
"globals": {
"__dirname": true
}
Got the idea from this similar question about the process global: https://stackoverflow.com/a/56777068/936907
I try to import a node module inside an Angular 8 web worker, but get an compile error 'Cannot find module'. Anyone know how to solve this?
I created a new worker inside my electron project with ng generate web-worker app, like described in the above mentioned ng documentation.
All works fine until i add some import like path or fs-extra e.g.:
/// <reference lib="webworker" />
import * as path from 'path';
addEventListener('message', ({ data }) => {
console.log(path.resolve('/'))
const response = `worker response to ${data}`;
postMessage(response);
});
This import works fine in any other ts component but inside the web worker i get a compile error with this message e.g.
Error: app/app.worker.ts:3:23 - error TS2307: Cannot find module 'path'.
How can i fix this? Maybe i need some additional parameter in the generated tsconfig.worker.json?
To reproduce the error, run:
$ git clone https://github.com/hoefling/stackoverflow-57774039
$ cd stackoverflow-57774039
$ yarn build
Or check out the project's build log on Travis.
Note:
1) I only found this as a similar problem, but the answer handles only custom modules.
2) I tested the same import with a minimal electron seed which uses web workers and it worked, but this example uses plain java script without angular.
1. TypeScript error
As you've noticed the first error is a TypeScript error. Looking at the tsconfig.worker.json I've found that it sets types to an empty array:
{
"compilerOptions": {
"types": [],
// ...
}
// ...
}
Specifying types turns off the automatic inclusion of #types packages. Which is a problem in this case because path has its type definitions in #types/node.
So let's fix that by explicitly adding node to the types array:
{
"compilerOptions": {
"types": [
"node"
],
// ...
}
// ...
}
This fixes the TypeScript error, however trying to build again we're greeted with a very similar error. This time from Webpack directly.
2. Webpack error
ERROR in ./src/app/app.worker.ts (./node_modules/worker-plugin/dist/loader.js!./src/app/app.worker.ts)
Module build failed (from ./node_modules/worker-plugin/dist/loader.js):
ModuleNotFoundError: Module not found: Error: Can't resolve 'path' in './src/app'
To figure this one out we need to dig quite a lot deeper...
Why it works everywhere else
First it's important to understand why importing path works in all the other modules. Webpack has the concept of targets (web, node, etc). Webpack uses this target to decide which default options and plugins to use.
Ordinarily the target of a Angular application using #angular-devkit/build-angular:browser would be web. However in your case, the postinstall:electron script actually patches node_modules to change that:
postinstall.js (parts omitted for brevity)
const f_angular = 'node_modules/#angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js';
fs.readFile(f_angular, 'utf8', function (err, data) {
var result = data.replace(/target: "electron-renderer",/g, '');
var result = result.replace(/target: "web",/g, '');
var result = result.replace(/return \{/g, 'return {target: "electron-renderer",');
fs.writeFile(f_angular, result, 'utf8');
});
The target electron-renderer is treated by Webpack similarily to node. Especially interesting for us: It adds the NodeTargetPlugin by default.
What does that plugin do, you wonder? It adds all known built in Node.js modules as externals. When building the application, Webpack will not attempt to bundle externals. Instead they are resolved using require at runtime. This is what makes importing path work, even though it's not installed as a module known to Webpack.
Why it doesn't work for the worker
The worker is compiled separately using the WorkerPlugin. In their documentation they state:
By default, WorkerPlugin doesn't run any of your configured Webpack plugins when bundling worker code - this avoids running things like html-webpack-plugin twice. For cases where it's necessary to apply a plugin to Worker code, use the plugins option.
Looking at the usage of WorkerPlugin deep within #angular-devkit we see the following:
#angular-devkit/src/angular-cli-files/models/webpack-configs/worker.js (simplified)
new WorkerPlugin({
globalObject: false,
plugins: [
getTypescriptWorkerPlugin(wco, workerTsConfigPath)
],
})
As we can see it uses the plugins option, but only for a single plugin which is responsible for the TypeScript compilation. This way the default plugins, configured by Webpack, including NodeTargetPlugin get lost and are not used for the worker.
Solution
To fix this we have to modify the Webpack config. And to do that we'll use #angular-builders/custom-webpack. Go ahead and install that package.
Next, open angular.json and update projects > angular-electron > architect > build:
"build": {
"builder": "#angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./extra-webpack.config.js"
}
// existing options
}
}
Repeat the same for serve.
Now, create extra-webpack.config.js in the same directory as angular.json:
const WorkerPlugin = require('worker-plugin');
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
module.exports = (config, options) => {
let workerPlugin = config.plugins.find(p => p instanceof WorkerPlugin);
if (workerPlugin) {
workerPlugin.options.plugins.push(new NodeTargetPlugin());
}
return config;
};
The file exports a function which will be called by #angular-builders/custom-webpack with the existing Webpack config object. We can then search all plugins for an instance of the WorkerPlugin and patch its options adding the NodeTargetPlugin.
In NodeJS I have:
const fs = require('fs');
if (!fs.existsSync("some_path")) {
...
}
But I get the error:
TypeError: fs.existsSync is not a function
After doing some searching, I read that Webpack brings its own require which clobbers node.js's require, so when you require a node.js core module that webpack can't resolve to one of your files or dependencies, it throws.
(My stack trace includes __webpack_require__)
But how can I fix it?
I was facing the same Error like TypeError: fs.existsSync is not a function
So, I figured out that one extra line was added automatically which was creating this issue in import.
after removing this line from import
import { TRUE } from "node-sass";
the issue has been resolved.
I had the same error that you have. Your vscode might have added a new module to your js file. Remove that module and your app should work just fine.
You can allow webpack to use the Node's require and include fs etc. by targeting node in the config:
module.exports = {
entry: './src/main.js',
target: 'node',
output: {
path: path.join(__dirname, 'build'),
filename: 'backend.js'
}
}
As described here: https://webpack.js.org/concepts/targets/ and https://webpack.js.org/configuration/target/
I was working on an electron application, I wanted to send a message from node and get in on the react side, but I was having that same issue when requiring ipcRenderer from electron, I tried
import { ipcRenderer } from 'electron';
and
const { ipceRenderer } = require('electron') This leads to an error due to webpack transforming node's require to its own webpack_require. See more info here
What worked for me was to use
const {ipcRenderer} = window.require('electron'); on the react side/renderer side from electron
In my case, I forgot that I'd only imported the promises API, const fs = require("fs").promises, which doesn't have exist or existsSync functions in Node 17.4.0.
To use exist or existsSync, make sure you've imported fs using the sync API (const fs = require("fs")).
Note: I'm adding this answer as a possible solution for future visitors to a canonical thread for the error, not OP who appears to have required fs correctly.
It is nothing to worry about, check your code for something like import { types } from "node-sass";, it would have mistakenly and automatically imported without you know. Remove that line, and everything should work perfectly.
Even if it is not type, it is something from node-sass in your node_modules file, and you can't edit that file.
So look for and remove import { types } from "node-sass"
In my case VSCode added a arbitrary import from electron. After removing it my application worked.
import { Menu } from 'electron';
In my case, i needed to send a message from the node to react. I tried importing ipcRenderer from 'electron'; and const ipceRenderer = require('electron') This results in an error owing to webpack changing the node's require to its own webpack require. See more info here
I am trying to run tests with async/await using mocha. The project architecture was setup before I started working on it and I have been trying to update it's node version to 8.9.4. The project is an isomorphic application and uses babel, gulp and webpack to run.
To run the tests we run a gulp task. There are two .bablerc files in the project. One in the root folder of the project and another in the test fodler.
Both have the same configuration:
{
"presets": [
["env", {"exclude": ["transform-regenerator"]}],
"react",
"stage-1"
],
"plugins": [
"babel-plugin-root-import"
]
}
When I run the app locally there is no error returned anymore. However when I run the tests with gulp test:api I constantly get the error: ReferenceError: regeneratorRuntime is not defined
This is my gulp file in the test folder:
var gulp = require('gulp')
var gutil = require('gulp-util')
var gulpLoadPlugins = require('gulp-load-plugins')
var plugins = gulpLoadPlugins()
var babel = require('gulp-babel')
require('babel-register')({
presets:["es2015", "react", "stage-1"]
});
// This is a cheap way of getting 'test:browser' to run fully before 'test:api' kicks in.
gulp.task('test', ['test:browser'], function(){
return gulp.start('test:api')
});
gulp.task('test:api', function () {
global.env = 'test'
gulp.src(['test/unit-tests/server/**/*.spec.js'], {read: false})
.pipe(plugins.mocha({reporter: 'spec'}))
.once('error', function (error) {
console.log(error)
process.exit(1);
})
.once('end', function () {
process.exit(0);
})
});
gulp.task('default', ['test']);
Any help on why this is happening wouldd be much appreciated.
Node version 8 already has support for async/await so you do not need Babel to transform it; indeed, your root .babelrc includes this preset to exclude the regenerator that would transform async/await (and introduce a dependency on regeneratorRuntime):
["env", {"exclude": ["transform-regenerator"]}]
However, in your test file, the configuration does not specify this preset. Instead, it specifies the preset "es2015", which does include the unwanted transform-regenerator (as you can see at https://babeljs.io/docs/plugins/preset-es2015/). If you change this to match the presets in the root .babelrc, you'll get more consistent results.
Strangely i ran into this issue after i upgraded to Node v8.10.0 from v8.6.x . I had used babel-require like so in my test-setup.js
require('babel-register')();
and the testing tools are Mocha,chai,enzyme + JSDOM . I was getting the same issue when i was making a async call to a API, also while using generator functions via sagas. Adding babel-polyfill seemed to have solved the issue.
require('babel-register')();
require('babel-polyfill');
i guess even babel docs themselves advocate using polyfill for generators and such
Polyfill not included
You must include a polyfill separately when using features that require it, like generators.
Ran into the same issue when running mocha tests from within Visual Studio Code.
The solution was to add the necessary babel plugins in the Visual Studio Code settings.json :
"mocha.requires": [
"babel-register",
"babel-polyfill"
],
I've run into this error before myself when using async/await, mocha, nyc, and when attempting to run coverage. There's never an issue when leveraging mocha for running tests, just with mocha tests while leveraging nyc for running coverage.
11) Filesystem:removeDirectory
Filesystem.removeDirectory()
Should delete the directory "./tmp".:
ReferenceError: regeneratorRuntime is not defined
at Context.<anonymous> (build/tests/filesystem.js:153:67)
at processImmediate (internal/timers.js:461:21)
You can fix the issue a couple of different ways.
Method 1 - NPM's package.json:
...
"nyc": {
"require": [
"#babel/register",
"#babel/polyfill"
],
...
},
...
It really depends which polyfill package you're using. It's recommended to use the scoped (#babel) variant: #babel/pollyfill. However, if you're using babel-polyfill then ensure that's what you reference.
Method 2 - Direct Import
your-test-file.js (es6/7):
...
import '#babel/polyfill';
...
OR
your-test-file.js (CommonJS):
...
require("#babel/polyfill");
...
Don't assign it to a variable, just import or require the package. Again, using the package name for the variant you've sourced. It includes the polyfill and resolves the error.
HTH
console.log statements output nothing at all in Jest. This was working for me yesterday, and all of sudden, it's not working today. I have made zero changes to my config and haven't installed any updates.
I'm not using the --forceExit option. Still seeing this issue.
Jest suppresses the console log message by default. In order to show the console log message, set silent option to false at the command line
set --silent=false in the command line:
npm run test -- --silent=false
You can run both options together like this --watch --verbose false if you want to also be watching the files and see the output.
for one time runs just do --verbose false
As per comment on https://github.com/facebook/jest/issues/2441,
Try setting verbose: false (or removing it) in the jest options in package.json.
This is a pretty old question and still there's no accepted answer. However, none of the suggested solutions worked for me (settings like --silent --verbose etc.). The main problem is that Jest changes the global console object. So, the easiest solution is to not use the global console object.
Instead import dedicated log functions from the console module and work with those:
import { error } from "console";
error("This is an error");
As easy as that.
Try using console.debug() instead.
Run console.debug('Message here', yourValueHere) inside test function and it should show in the console output when running test script. You can verify if it works using Ctrl+F and find Message here in the standard output.
This does the trick of showing output in the console, while it is not an answer quite on how to use console.log I understand.
I am running #testing-library/jest-dom and jest-junit 12.0.0 as devDependencies.
jest-junit has a minimal configuration of
"jest-junit": {
"usePathForSuiteName": "true"
},
in package.json. This is mainly to configure coverage reporting.
jest is configured like this:
"jest": {
"testMatch": [
"**/__tests__/**/*.[jt]s?(x)",
"**/?(*.)+(spec|test).[jt]s?(x)",
"!**/utilities.ts",
],
Check for your command line flags in package.json to see that you don't have --silent in there.
in addition to --verbose option which can cause this as mentioned, be aware that the --watch may also cause this bug.
One of the potential reason that logging is not printing is due to console.log has been mocked. Something as below
// jest-setup.js
global.console = {
// eslint-disable-next-line no-undef
log: jest.fn(), // console.log are ignored in tests
// log: console.log,
// Keep native behaviour for other methods, use those to print out things in your own tests, not `console.log`
error: console.error,
warn: console.warn,
info: console.info,
debug: console.debug,
};
// package.json
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
],
"setupFilesAfterEnv": [
"#testing-library/jest-native/extend-expect",
"<rootDir>/src/config/jest-setup.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.test.{ts,tsx}"
]
},
This is commonly used if you wish to disable console.log in jest
Also be sure that your jest config does not have silent: true. In my case, I didn't realize that someone else had added that to our config.
I don't see it in the list of config options, but the command line flag is documented here.
If using Webstorm with Jest configuration, click on the file name instead of the test name.
Having tried a few of the config options in the previous replies, using console.debug() instead of console.log() worked.
In my case, the issue was caused by [only] flag in:
it.only() or test.only('some text',()=>{})
According to the v27 docs silent is what you want here. verbose false (the default) prevents Jest from outputting the result of every test in a hierarchy while silent true (the default) will:
Prevent tests from printing messages through the console.
Use npx jest --silent false if you want to run Jest with that option from the CLI. Tested this just now with console.log and it works as expected.
Tried the advice given regarding jest config settings to no avail. Instead, in my case, the issue seemed related to not awaiting asynchronous code:
test("test", async () => {
console.log("Does output")
new Promise(resolve => {
// some expectation depending on async code
setTimeout(() => resolve(console.log("Does not output")) , 1)
})
})
Rather, awaiting the promise does output the async log:
test("test", async () => {
console.log("Does output")
await new Promise(resolve => {
// some expectation depending on async code
setTimeout(() => resolve(console.log("Does output")) , 1)
})
})
Possibly related background:
https://github.com/facebook/jest/issues/2441
Try using console.info() which is an alias for console.log(). I tried almost all the above answers but still console.log() didn't worked for me by any means. So, used console.info() which did the work.
This is what worked for me: jest --verbose true
In my case the problem was that the logs where made when the module is required, so before the start of an actual test case. Change from a top-level import to using require inside the test case fixed the problem.
In my case the problem was importing the functions from the compiled version (present in dist folder) instead of the src folder. And therefore it was using the old version. So rebuilding the project and/or importing from src fixed my issue.
On MacOS with jest version 26.6.3 I had to append --silent="false"
renaming my file to index.test.js from index.spec.js did the trick for me.