External imports in Babel 7 do not get transpiled - node.js

I'm currently migrating a codebase from Babel 6 to 7. The code is made up of multiple individual projects with their own configs.
The main project imports files from external however the scripts being imported from external by main aren't being transpiled and fails on "Unexpected token import". Scripts located directly in main do transpile correctly.
I'm using the following command within the main project to transpile the scripts:
babel-node ./index.js
Another project uses Webpack to do the same thing and handles everything correctly.
This setup also worked fine with Babel 6.
.babelrc for main
{
"ignore": [
"node_modules"
],
"presets": [
["#babel/preset-env", {
"targets": {
"node": "current"
},
"useBuiltIns": "entry"
}]
],
"plugins": [
[
"module-resolver", {
"alias": {
"External": "../external"
}
}
],
"#babel/plugin-proposal-decorators",
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-proposal-export-default-from",
"#babel/plugin-proposal-export-namespace-from",
"#babel/plugin-proposal-class-properties"
]}
.babelrc for external
{
"presets": [
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-transform-runtime"
]}
I've created an example to detail my problem at:
https://gitlab.com/nerdyman/babel-7-external-import-broken
TL;DR I'm trying to import scripts from outside of a project's root directory but they don't get transpiled by Babel, the scripts from within the project do transpile.

I've managed to fix this by following this comment.
The solution is:
Move .babelrc in the main project to babel.config.js and make it a CommonJS module
Add --ignore=node_modules when running babel-node from the main project
This still seems pretty hacky and Babel doesn't seem to acknowledge the ignore property within babel.config.js it must be specified as a flag.
Babel 7 appears to only allow imports within the directory the babel config is in, however explicitly setting the --ignore flag overrides this.
You can view my working demo and the diff of what I changed to get it working.
The issue is still open on GitHub so there may be a better solution in the future.

current directory's .babelrc won't be loaded while import files in external directory, you may place a .babelrc in that directory and set its presets by relative path(instead of short name):
{ "presets": ["..\pad\node_modules\babel-preset-env"],
"retainLines": true }

Related

How can I declare two different configurations to .stylelint

I use Stylelint on my project to check styles.
I'm using a plugin that should only run on one folder. And the main configuration that is done for the whole project.
.stylelint file:
{
"extends": "stylelint-config-standard",
"plugins": [
"stylelint-scss",
"stylelint-no-px"
],
"rules": {
...
}
}
and run command: "stylelint": "stylelint \"src/**/*.scss\"".
But i have to use "stylelint-no-px" pluggin only on src/app folder
There was an idea to create two launch commands for different folders(src/app and whole src), but in this case app folder would be checked twice.
Is there any way to create two different configs that could inherit from each other? For example, the first one is called only on src/app folder, and the second without a plugin is called on src/ folder and excludes src/app folder.
You can use the overrides configuration property to modify a Stylelint config for a specified set of files.
For example, to additionally run the stylelint-no-px plugin on the *.scss files in the src/app directory:
{
"extends": "stylelint-config-standard",
"plugins": [
"stylelint-scss",
"stylelint-no-px"
],
"rules": {
... // don't include meowtec/no-px here
},
"overrides": [
{
"files": ["src/app/*.scss", "src/app/**/*.scss"],
"rules": {
"meowtec/no-px": true
}
}
]
}
You can then continue to run Stylelint only once using the following command:
stylelint "src/**/*.scss"

Jest moduleNameMapper and NPM package exports

I am developing fullstack NPM packages with multiple entrypoints (namely client, server and sometimes tests), using the exports property of package.json.
I also use a small hack to make TS work with exports until it's officially supported (see this Stack Overflow post, this hackish solution and this ticket).
The package.json ends up looking like this:
{
"name": "#vulcanjs/graphql",
"version": "0.4.7",
"main": "./dist/index.js",
"files": [
"dist/"
],
"exports": {
".": "./dist/index.js",
"./server": "./dist/server/index.js",
"./testing": "./dist/testing.js"
},
"types": "./dist/index.d.ts",
"typesVersions": {
"*": {
"server": [
"./dist/server/index.d.ts"
],
"testing": [
"./dist/testing.d.ts"
]
}
},
"description": "Vulcan graphQL schema generator",
...
You can then import using either #vulcanjs/graphql for shared code, and #vulcanjs/graphql/server for Node.js-only code.
It works perfect in my Next.js app. However, it seems to break Jest moduleNameMapper.
First, I had this:
moduleNameMapper: {
"#vulcanjs/(.*)": [
"<rootDir>/node_modules/#vulcanjs/$1",
],
},
The error is:
Configuration error:
Could not locate module #vulcanjs/graphql/server mapped as:
[
"/code/vulcan-next/node_modules/#vulcanjs/graphql/server",
].
The problem is that it tries to find a package named #vulcanjs/graphql/server: yet "server" is not a different package, it's an entrypoint of #vulcanjs/graphql.
I've also tried this:
moduleNameMapper: {
"#vulcanjs/(.*)/(.*)": [
"<rootDir>/node_modules/#vulcanjs/$1",
],
},
With this config, #vulcanjs/graphql/server is mapped to #vulcanjs/graphql. The problem is that now, server code is not found. I've checked and the problem is that this solution totally removes the /server: so #vulcanjs/graphql/server points to the main entrypoints instead of the server entrypoint.
Finally I did try to remove the moduleNameMapper, but then #vulcanjs/graphql/server package is not found by Jest. Note that I need the mapper for a use case I did not demonstrate here, so getting rid of it is possible but not the best solution.
The bug can be reproduced by installing the framework: https://github.com/VulcanJS/vulcan-next. You can clone, yarn install, unskip the test in src/models/tests/sampleModel.server.test.ts and run yarn run test:unit sampleModel. It will show the error.
Any idea how I could fix this?

Resolving relative paths in a serverless Nodejs app in Typescript

We have a NodeJS app written in typescript. We use modules using relative paths
e.g.
import foo from '#/bar';
We have following paths entry in tsconfig.json
"paths": {
"#/*": [
"./*"
]
}
As typescript does not have path transformation support, we are using ttypescript to compile and override tsconfig.json with tsconfig.build.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"plugins": [
{
"transform": "#zerollup/ts-transform-paths"
}
]
},
"exclude": ["node_modules/**", "tests/**"]
}
and use yarn to build the code
yarn clean && ttsc --project ./tsconfig.build.json
Now this build the code and converts the relative #module paths to absolute.
Next we are using Serverless framework to build and deploy this code as lambda. Serverless uses tsconfig.json to build the code and effectively ignore the custom path transformation.
Question:
is it possible to solve the above problem without using ttypescript and plugin?
Is it possible to configure serverless to use ttypescript and custom tsconfig
Any other way to solve the problem?
Thanks

Error while loading config - You appear to be using a native ECMAScript module configuration file (Jest)

UPDATED.
This error is coming up when I am making a pull request. There is a github workflow audit that runs checks on the pull request and it loads the test file from another repository.
- name: Run Audits
run: npx jest audits/ch-2 --json --outputFile=audits/ch-2.json --noStackTrace
Test suite failed to run
/Users/frankukachukwu/StudioProjects/covid-19-estimator-tksilicon-js/babel.config.js: Error while loading config - You appear to be using a native ECMAScript module configuration file, which is only supported when running Babel asynchronously.
How do I solve this issue?
SOLVED: For anyone who encounters this problem. This has got to do with Babel settings. The use of .mjs, cjs or js extension for the babel.config.extension. In my case where I was running LTE Node 12.6.2. I needed this configuration at the root of my directory babel.config.cjs. cjs is what is applicable for Nodejs when using "type"="module". See more about it here on babel docs.
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current'
}
}
]
]
};
And jest.config.cjs at the root too.
In addition to "cjs" solution, I was able to resolve this issue by converting babel.config.js to babel.config.json:
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "current"
}
}
],
"#babel/preset-typescript"
]
}

Babel doesn't ignore node_modules directory, although it is in "ignore" config

For some reason babel doesn't ignore node_modules directory, although I specified it in "ignore" field of .babelrc file. Why does it happen? How to make babel act as expected?
My goal is to compress and mangle all .js files in my ExpressJS app (particularly my all back end code) before I push my app to remote repo and then to server. So I use babel and babili.
Here is my .babelrc config:
{
"presets": [
["latest", {
"modules": false
}]
],
"env": {
"development": {
"presets": ["stage-0", "react", "babili"]
},
"production": {
"presets": ["stage-0", "react", "babili"]
}
},
"ignore": [
"node_modules",
"assets",
"view",
"public",
"test",
"spec",
"logs",
"lib/jasmine_examples",
"db"
]
}
And I run babel from command line like this:
./node_modules/.bin/babel . -d ~/app_compressed/
And babel starts compressing node_modules directory:
node_modules\apache-crypt\gensrc\index.js -> C:\Users\user\app_compressed\node_modules\apache-crypt\gensrc\index.js
node_modules\apache-md5\gensrc\index.js -> C:\Users\user\app_compressed\node_modules\apache-md5\gensrc\index.js
node_modules\babel-preset-env\data\built-in-features.js -> C:\Users\user\app_compressed\node_modules\babel-preset-env\data\built-in-features.js
node_modules\babel-preset-env\data\plugin-features.js -> C:\Users\user\app_compressed\node_modules\babel-preset-env\data\plugin-features.js
node_modules\babel-preset-env\lib\default-includes.js -> C:\Users\user\app_compressed\node_modules\babel-preset-env\lib\default-includes.js
node_modules\babel-preset-env\lib\index.js -> C:\Users\user\app_compressed\node_modules\babel-preset-env\lib\index.js
Literally wrong behavior. How to fix it? How to make babel ignore folders specified in config?
ignore get array of regexes so try like this
ignore: [
/node_modules/,
...,
]
or you can pass a callback function like this
ignore: [
/node_modules/,
function(filepath) {
return filepath !== "/path/to/es6-file.js";
},
]
Babel dev team say that there is a bug and ignored in config file doesn't work now.
However, I found that if you pass ignored directories in command line (with --ignored option), all works well, as expected. You can even pass globs in command line, like **/drafts
./node_modules/.bin/babel . -d ~/app_compressed/ --ignore node_modules,test,assets,stuff,views,public,test,spec,logs,lib/jasmine_examples,db,routes/api/drafts,**/drafts
I had the same problem after moving a Vue project from Cloud9 env to my PC and installing npm dependencies.
Solved this by:
updating the Node.js with nvm for windows
installing the Vue CLI globally and then running build in the Vue UI.
I am not sure what helped though.

Resources