How to ignore non-js files with babel/register - javascript

When my Node app includes the routes from my App I want to ignore non-js files e.g.
import './scss/App.scss' // i.e via Router.js -> Routes.js -> App.js
At the moment Node is obviously throwing a parse error as it's trying to parse the scss as js. The babel hook currently looks like this:
require('babel/register')({
stage: 0
});
Any ideas how I can make babel ignore them? Thanks

Turns out it was node that needed the tweak:
require.extensions['.scss'] = () => {};

You can create .babelrc file and set ignore rule:
{
"stage": 0,
"ignore": [
"*.scss"
]
}
You can read more about this here - https://babeljs.io/docs/usage/babelrc/

You can use babel-plugin-transform-import-ignore to ignore matched imports. All matched import statements will be removed after compilation.
{
plugins: [
[
"babel-plugin-transform-import-ignore",
{
patterns: [".scss"]
}
]
]
}

Related

Nodejs with JEST how to import using ES6 and relative path?

I want to avoid this:
const SomeMethod = require('../shared/SomeMethod')
And instead use something more modern like this:
import { SomeMethod } from '/shared'
(under the hood): the /shared directory includes an index file of course, returning the object with the SomeMethod property which is also includes to a file.
As I am using JEST, I need two things to get around: 1 is that the node installed supports ES6 imports and 2 is that JEST will be familiar with relative path - notice that I have used the **/**shared so it means - go to the src directory and start from there.
But how to achieve this?
You can achieve this using babel. According to the documentation of jest, you need to do the following
yarn add --dev babel-jest #babel/core #babel/preset-env
and then create babel.config.js at the root of your project with the following content
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};
You can look into the documentation for more
Here is a step by step process of the same which is addressing the same problem
In order to use absolute path for Jest add the following line in jest.config.js
module.exports = {
moduleDirectories: ['node_modules', 'src'],
...
};
here, src is considered as the root. You may need to change this one according to your folder name.
For more information you can follow this article

how can I remove unused code when I build my bundle?

I am not sure how to organize my js code.
Our front end is customized to different customers. Majority of the base code is common across all customers. However there are cases where certain functionality is overridden for each customer.
For example if we have 2 functions Function1 and Function2.
Customer1 uses Function1 while Customer2 uses Function2. How can I make sure that when I build the code for Customer, Function2 will not be included in the bundle? And when I build the code for Customer2, then Function1 will not be included int he bundle?
The other option I have, and that I am trying to avoid, is to have a separate code repo for each customer.
I think what you need is Tree-Shaking in webpack.
Tree shaking can be a stubborn process depending on how the library you are using in your application is developed.
If you find that you are using a module that does not shake dead code properly, you can always use the babel-plugin-import plugin. This plugin will build your bundle with only the code you import and nothing else. Here is an example of my babel 7.x config file. I use it to remove a lot of code that was not being tree-shaken by webpack from material-ui.
{
"presets": [
"#babel/preset-typescript",
"#babel/preset-react"
],
"plugins": [
[
"babel-plugin-import",
{
"libraryName": "#material-ui/core",
"libraryDirectory": "/",
"camel2DashComponentName": false
},
"core"
],
[
"babel-plugin-import",
{
"libraryName": "#material-ui/icons",
"libraryDirectory": "/",
"camel2DashComponentName": false
},
"icons"
]
]
}
When using this plugin in certain libraries, some of your imports also may break and you may need to import certain things on their own. I had to do this with material-ui's makeStyles function.
Feel free to remove what is unnecessary to you and keep the parts that help :).
At webpack configuration, optimization/usedExports: true will remove unused code.
webpack.config.js
module.exports = [
{
entry: "./main.js",
output: {
filename: "output.js"
},
optimization: {
usedExports: true, // <- remove unused function
}
},
{
entry: "./main.js",
output: {
filename: "without.js"
},
optimization: {
usedExports: false, // <- no remove unused function
}
}
];
lib.js
exports.usedFunction = () => {
return 0;
};
exports.unusedFunction = () =>{
return 1;
};
main.js
// Not working
// const lib = require("./lib");
// const usedFunction = lib.usedFunction;
// Working
const usedFunction = require("./lib").usedFunction;
usedFunction()
```shell
$ webpack
Generated Output file:
dist/output.js
(()=>{var r={451:(r,t)=>{t.W=()=>0}},t={};(0,function e(o){var n=t[o];if(void 0!==n)return n.exports;var p=t[o]={exports:{}};return r[o](p,p.exports,e),p.exports}(451).W)()})();
dist/without.js
(()=>{var n={451:(n,r)=>{r.usedFunction=()=>0,r.unusedFunction=()=>1}},r={};(0,function t(u){var e=r[u];if(void 0!==e)return e.exports;var o=r[u]={exports:{}};return n[u](o,o.exports,t),o.exports}(451).usedFunction)()})();
^^^^^^^^^^^

Compile template files/stubs into JS variables with Laravel mix

I have a folder /resources/js/stubs. In that folder sits a few files, lets say User.stub, Controller.stub and Migration.stub. I would like to use the content of these files in my javascript by doing something like this
import Templates from './Templates.js'
console.log(Templates.User)
// The content of User.stub is printed
I don't want to use this approach
module.exports = name => `
...
`
I could also use the backend to load the files into the view but I would prefer not to.
So then that requires preprocessing. Can I do it with Laravel mix somehow? If not what are my options, what do I need to add to my Laravel app?
partial solution
Thanks to Diogo Sgrillo for pointing out this solution in the comment.
Install raw-loader
yarn add raw-loader --dev
webpack.mix.js
Add this configuration (In my case all the files will be named with a .stub extension.):
mix.webpackConfig({
module: {
rules: [
{
test: /\.stub$/i,
use: 'raw-loader',
},
],
},
});
Also add a separate pipe in webpack.mix.js like this:
mix.js('src/templates/index.js', 'src/templates.js')
It will compile a list of templates in index.js file and put them in templates.js.
src/templates/index.js
// Dynamically load all stubs using raw-loader (see webpack.mix.js)
let stubs = require.context('./', true, /\.stub$/i);
// Create a object with the filename as key and content as value
exports.stubs = stubs.keys().reduce((result, key) => {
return {
[key.replace(/\.\//,'').replace(/\.stub$/,'')] : stubs(key).default,
...result
}
}, {});
export default { /* dont remove this export default or it will break !?? */}
Later it can be used like this:
let templates = require('./templates.js')
console.log(templates['User.php'])
Please comment or add another answer on how to do this more smooth. What is the difference between exports/export? I cant use import with this method, only require and it breaks if I try to export default (or remove export default.

Jest transformIgnorePatterns not working

I have spent a long time looking at other questions about this and looking at other projects on Github but none of the answers seem to work for me.
I am loading a third party library in my project, and when running Jest tests I get the error
export default portalCommunication;
^^^^^^
SyntaxError: Unexpected token export
> 1 | import portalCommunication from 'mathletics-portal-communication-service';
I have tried updating my Jest config in many ways to get it to transpile this library but I always get the same error.
This is my current jest.config.js file:
module.exports = {
moduleNameMapper: {
'\\.(css|scss)$': 'identity-obj-proxy',
'\\.svg$': '<rootDir>/test/mocks/svg-mock.js'
},
setupFiles: ['./test/test-setup.js'],
transformIgnorePatterns: [
'<rootDir>/node_modules/(?!mathletics-portal-communication-service)'
]
};
I have also tried adding the transform property to run babel-jest against this mathletics-portal-communication-service directory.
Please help!
The transformIgnorePatterns didn't work for me until I changed my .babelrc to babel.config.js, like this:
module.exports = {
"presets": [
"#babel/preset-env"
]
};
as seen on this comment: https://github.com/facebook/jest/issues/6229#issuecomment-403539460
As a workaround for now I have changed my config to use the moduleNameMapper option to load a mock class for that library instead. I would have preferred to use transformIgnorePatterns instead so would still appreciate any ideas.
New config:
module.exports = {
moduleNameMapper: {
'\\.(css|scss)$': 'identity-obj-proxy',
'\\.svg$': '<rootDir>/test/mocks/svg-mock.js',
'mathletics-portal-communication-service': '<rootDir>/test/mocks/mathletics-portal-communication-service-mock.js'
},
setupFiles: ['./test/test-setup.js']
};
Another team at my org added some common module. This was not transpiled and so the issue.
I followed this: https://babeljs.io/docs/en/configuration#whats-your-use-case
Converted my .babelrc to babel.config.json
in jest config added this:
transformIgnorePatterns: ['/node_modules/(?!(#companyName)/).*/'],
This solved my problem.
Adding trailing slash fix this for me:
{
// ...
transformIgnorePatterns: [
'<rootDir>/node_modules/(?!mathletics-portal-communication-service/)'
]
};
It might be your use of rootDir. Try:
"transformIgnorePatterns": [
"node_modules/(?!(mathletics-portal-communication-service))"
]

'Subject' is not exported by rxjs in rollup.js

I am trying to set up my project to use rollup, as part of an angular2 move to AOT compilation, however, I am getting the following issue.
Error: 'Subject' is not exported by node_modules\rxjs\Subject.js
This is my rollup.js file:
import rollup from 'rollup';
import nodeResolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify'
export default {
entry: 'client/main.js',
dest: 'public/assets/js/build.js',
sourceMap: false,
format: 'iife',
plugins: [
nodeResolve({jsnext: true, module: true}),
commonjs({
include: 'node_modules/rxjs/**',
include: 'node_modules/angular2-jwt/**',
}),
uglify()
]
}
Why is this happening, I have followed the angular2 cookbook guide?
You'll need to use the namedExports option with rollup-plugin-commonjs: https://github.com/rollup/rollup-plugin-commonjs#custom-named-exports.
Also, you may find it useful to include: 'node_modules/**' rather than individual packages, as otherwise any dependencies of your dependencies will bypass the plugin (in the config above, you have duplicate include properties – perhaps that's just a typo? If you need to pass multiple values, use an array).
commonjs({
include: 'node_modules/**',
namedExports: {
'node_modules/rxjs/Subject.js': [ 'Subject' ]
}
})
I finally figured this out on my system.
The named export solution is wrong since rollup-plugin-commonjs will handle the exports in Subject.js just fine.
The problem for me was the "includes" option in rollup-plugin-commonjs.
There are two issues.
Number one: when specifying the includes in the options as "node_modules/rxjs/**" you have to be sure the full path resolves to where you expect it to.
Example:
I run my build command from "c:/foo/build" but my files are in "c:/my-source" then the include patterns might resolve to "c:/build/node_modules" which means when the commonjs plugin is checking if it should handle "node_modules/rxjs/" it will see that "c:/my-source/node_modules/rxjs/" does not match "c:/build/node_modules/rxjs/**" thus it will not convert the exports to ES6.
The second issue is case sensitivity. The include patterns are case sensitive. This tripped me up too.
Both of these issues can be confirmed by opening the "node_modules\rollup-plugin-commonjs\dist\rollup-plugin-commonjs.cjs.js" file and debugging the "transform" function.
If you modify the code (at the very beginning of the transform function) to be something like this
if (id.includes('rxjs\\Subject.js')) {
debugger;
}
and then run the code in a debugger, you can step through the code until it gets to the filter function. There you will see the filter function is skipping the "rxjs/Subject.js" file.
I almost guarantee this is the problem when the error occurs.
I have found that this can happen in combination with symlinks.

Categories

Resources