How to prevent babel transform operator 'typeof' in JS - babeljs

I develope a JS SDK with ES6 grammar. The file size of the SDK is about 8Kb. After compile it with babel, size of SDK is about 20Kb. I find that babel transforms operator typeof with a helper "babel-runtime/helpers/typeof", which increase my SDK's size. If I don't use typeof in my SDK, the file size of my SDK is about 7Kb.
_validateCallback(fnName, arg) {
if (typeof arg !== 'function') {
throw new TypeError(`[${fnName}]'s arguments[0] must be a function, but get a ${typeof arg}`);
}
}
The detail of my .babelrc:
{
"presets": [
[
"env",
{
"targets": {
"browsers": [
"last 2 versions",
"ie >= 9"
]
}
}
],
"stage-2"
],
"plugins": [
"transform-runtime"
]
}
The devDependencies of package.json
{
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-2": "^6.24.1",
"webpack": "^4.37.0",
"webpack-cli": "^3.3.6"
}
The detail of my webpack.config.js
{
mode: 'production',
entry: './main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'botapp-sdk.' + PACKAGE.version + '.js',
library: 'BotApp',
libraryTarget: 'var',
},
plugins: [
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.BannerPlugin(PACKAGE.name + ' - ' + PACKAGE.version),
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
}
}
I need to prevent babel to transform 'typeof', so that I can reduce file size of my SDK.
Is there any way to prevent babel transform operator typeof ?

I have been find a way to solve the question:
## -8,7 +8,10 ##
"last 2 versions",
"ie >= 9"
]
- }
+ },
+ "exclude": [
+ "transform-es2015-typeof-symbol"
+ ]
}
],
"stage-2"
The detail of exclude see: https://babeljs.io/docs/en/babel-preset-env#exclude

I have the same issue. I have no idea, what is the problem with typeof, as it seem to be a day one feature of ES. There is some issue with Symbol object, but I didn't find any article highlighting the problem.
Anyways, the possible solution is just to drop typeof:
!(arg instanceOf Function)
Also, a solid workaround is an oldstyle typechecker:
Object.prototype.toString.call(alert) === '[object Function]'
My prefered way is just to check if call exists:
args.call && console.log('OK')
The benefit of typeof is that it works fine with undeclared variables.
In your case, it doesn't matter, because arg is declared as a function argument. In case it's not, you should use try/catch to avoid possible ReferenceError.

Related

Unable to use Jest test in svelte component when carbon-icons-svelte is imported from inside node_modules error: Jest encountered an unexpected token

I would like to import an icon from package carbon-icons-svelte to my svelte component. It works very well in browser but I can't test this component. Testes worked good before import of carbon icons.
This is my configuration:
svelte.config.test.cjs
const preprocess = require('svelte-preprocess');
require('dotenv').config()
module.exports = {
preprocess: preprocess({
replace: [[/import.meta.env.([A-Z_]+)/, (importMeta) =>
{ return JSON.stringify(eval(importMeta.replace('import.meta', 'process')))} ]]
})
};
jest.config.cjs
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig.json');
module.exports = {
transform: {
'^.+\\.svelte$': [
'svelte-jester',
{
preprocess: './svelte.config.test.cjs'
}
],
"^.+\\.(js)$": "babel-jest",
'^.+\\.(ts)$': [require.resolve('jest-chain-transform'),
{ transformers: ['../../../build-utils/importMetaTransformer.cjs', 'ts-jest'] }
]
},
testMatch: ["**/spec/**/*.js"],
moduleFileExtensions: ['js', 'ts', 'svelte'],
setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {prefix: '<rootDir>/'})
};
tsconfig.json
{
"compilerOptions": {
"moduleResolution": "node",
"module": "es2020",
"lib": ["es2020", "DOM"],
"target": "es2019",
"importsNotUsedAsValues": "error",
"allowSyntheticDefaultImports": true,
"isolatedModules": true,
"resolveJsonModule": true,
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"allowJs": true,
"checkJs": true,
"paths": {
"$/*": ["src/*"]
}
},
"include": [
"src/**/*.d.ts",
"src/**/*.js",
"src/**/*.ts",
"src/**/*.svelte",
"src/**/*.svelte-kit",
"./jest-setup.ts"
],
"exclude": ["node_modules"]
}
I have this information about an error in jest:
Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
/home/dev/src/iroco-app-client/node_modules/carbon-icons-svelte/lib/Information32/Information32.svelte:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){<script>
^
SyntaxError: Unexpected token '<'
9 | import { createPopper } from '#popperjs/core';
10 | import Information32 from 'carbon-icons-svelte/lib/Information32/Information32.svelte';
> 11 |
| ^
I added to jest.config.test.cjs
transformIgnorePatterns: ["<rootDir>/node_modules/(?!(carbon-icons-svelte))"]
after moduleNameMapper but still it doesn't work.
Thanks for your help.
running on node 16, i changed my babel to cjs and it worked for me, this is what it looks like
module.export = {
presets: [['#babel/preset-env', { targets: { node: 'current' } }], '#babel/preset-typescript']
};
my jest.config.js
const config = {
testEnvironment: 'jsdom',
transform: {
'^.+\\.js$': 'babel-jest',
'^.+\\.ts$': 'ts-jest',
'^.+\\.svelte$': ['svelte-jester', { preprocess: true }]
},
transformIgnorePatterns: [
'<rootDir>/node_modules/(?!(carbon-icons-svelte))',
'<rootDir>/node_modules/(?!(carbon-components-svelte))'
],
moduleFileExtensions: ['js', 'ts', 'svelte']
};
export default config;

Unable to resolve module when using babel module resolver + eslint + index files in react application

I am trying to use babel module resolver plugin with eslint + create react app but I am unable to start the application, getting the error
internal/modules/cjs/loader.js:1237
throw err;
^
SyntaxError: C:\Users\enisr\Desktop\projects\pcPartPicker\jsconfig.json:
Unexpected token } in JSON at position 166
at parse (<anonymous>)
I have set up a git repo showcasing the problem https://github.com/sgoulas/pcPartPicker
I have read the instructions in the docs and in the original repository and I am unable to configure it correctly.
My configuration files are the following:
.babelrc
{
"plugins": [
["module-resolver", {
"extensions": [
".js",
".jsx",
".es",
".es6",
".mjs"
],
"root": ["./src"],
"alias": {
"#components": "./src/components"
}
}
]
]
}
jsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"*": ["src/*"],
"#components/*": ["./src/components/*"],
}
}
}
webpack.config.dev.js
var path = require("path");
module.exports = {
include: path.appSrc,
loader: require.resolve("babel-loader"),
options: {
plugins: [
[
"module-resolver",
{
root: ["./src/App"],
alias: {
"#components": "./src/components",
},
},
],
],
cacheDirectory: true,
},
};
My component:
import { GPUtable, CPUtable } from "#components/Tables";
const App = () => {
return (
<>
<GPUtable />
<CPUtable />
</>
);
};
export default App;
There are some minor fixes you need to make (below), but the main issue is that Create React App does not expose the webpack config, you'll need to eject to edit that.
npm run eject
Merge the babel configs: delete the babel key + value at the bottom of the package.json, and paste the value into your bablrc ("presets": ["react-app"],).
Add import React from 'react'; to the top of App.js
Confirmed locally that the app will run.
Other suggested fixes
Your jsconfig has a trailing comma after the array value in #components/*. You need to remove it because JSON doesn’t support them.
You need to fix the include path in weback.config.dev.js. appSrc isn't something defined on the node path module. Try using path.resolve(__dirname, 'src') - the example in their docs is creating/importing a paths object with appSrc pointing to this value.
You're missing test: /\.(js|jsx|mjs)$/, in webpack.config.dev.js.

Jest Test Support for the experimental syntax 'jsx' isn't currently enabled

I am writing first tests for my app and just install Jest.
My test is pretty simple, so I don't think the error I am getting is coming from there.
import React from 'react';
import renderer from 'react-test-renderer';
import FancyInput from './FancyInput';
describe('FancyInput', () => {
it('should render correctly', () => {
expect(
renderer.create(
<FancyInput />
)
).toMatchSnapshot();
});
});
Error when run the test is Support for the experimental syntax 'jsx' isn't currently enabled
also
`Add #babel/preset-react (https://git.io/JfeDR) to the 'presets' section of your Babel config to enable transformation.
If you want to leave it as-is, add #babel/plugin-syntax-jsx (https://git.io/vb4yA) to the 'plugins' section to enable parsing.`
My webpack file has the following thing:
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-react',
],
plugins: [
["#babel/plugin-proposal-decorators", { "legacy": true }],
["#babel/plugin-proposal-optional-chaining"],
["#babel/plugin-syntax-jsx"],
]
}
}
},
also my package.json has all the plugins I believe are necessary
"#babel/plugin-proposal-class-properties": "^7.10.4",
"#babel/plugin-proposal-decorators": "^7.4.4",
"#babel/plugin-proposal-optional-chaining": "^7.11.0",
"#babel/plugin-syntax-jsx": "^7.10.4",
"#babel/preset-react": "^7.0.0",
what am I missing here ?

regeneratorRuntime is not defined (how keep babel from including that polyfill?)

I continue to get:
App.jsx:11 Uncaught ReferenceError: regeneratorRuntime is not defined
on any line that does an async. I don't what that polyfill, but I am having a hard time getting rid of it:
app.jsx:11)
const fetcher = (async () => {
"#babel/cli": "^7.4.4",
"#babel/core": "^7.4.4",
"#babel/preset-env": "^7.4.4",
"#babel/preset-react": "^7.0.0",
"#types/react": "^16.8.17",
"babel-preset-env": "^1.7.0"
here is the .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"chrome": ">70",
},
"exclude": ["transform-regenerator"]
},
"#babel/preset-react"
]
]
}
If you want to use async, await with (ES6 or ES Next) then you must need to install #babel/polyfill but you don't need to write anything in babelrc file. Just install
npm install --save #babel/polyfill
From the documentation:
Because this is a polyfill (which will run before your source code),
we need it to be a dependency, not a devDependency
And finally you need to import #bable/polyfill in your mainJS (App.js) file like:
import "#babel/polyfill";
This appears to be a bug in the parcel js bundler.
https://github.com/babel/babel/issues/9971

Target [Illuminate\Contracts\Routing\ResponseFactory] is not instantiable

I am trying to return a response like this:
return response()->json(['name' => 'Abigail', 'state' => 'CA']);
however, I got error:
Target [Illuminate\Contracts\Routing\ResponseFactory] is not instantiable.
Any idea?
Here is my composer.json:
{
"name": "laravel/lumen",
"description": "The Laravel Lumen Framework.",
"keywords": [
"framework",
"laravel",
"lumen"
],
"license": "MIT",
"type": "project",
"require": {
"php": ">=5.5.9",
"laravel/lumen-framework": "5.2.*",
"vlucas/phpdotenv": "~2.2",
"generationtux/jwt-artisan": "^0.1.7",
"barryvdh/laravel-cors": "^0.8.0",
"neomerx/cors-illuminate": "^1.1",
"fenos/notifynder": "3.1.*",
"franzose/closure-table": "^4.1",
"mlntn/lumen-artisan-serve": "~1",
"guzzlehttp/guzzle": "~6.0",
"league/flysystem": " ~1.0",
"bugsnag/bugsnag-laravel": "^2.0"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
"phpunit/phpunit": "~4.0"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"GuzzleHttp\\": "/vendor/guzzlehttp/"
},
"classmap": [
"database/"
]
},
"autoload-dev": {
"classmap": [
"tests/",
"database/"
]
},
"config": {
"preferred-install": "dist"
}
}
I still get the error in 2020. Here's an updated version of the solution by #sunben:
In bootstrap/app.php, uncomment the following line
$app->register(App\Providers\AppServiceProvider::class);
Then in app\Providers\AppServiceProvider.php, update register method to add:
$this->app->singleton(\Illuminate\Contracts\Routing\ResponseFactory::class, function() {
return new \Laravel\Lumen\Http\ResponseFactory();
});
Might be late but found the solution.
In bootstrap/app.php, uncomment the following line
$app->register(App\Providers\AppServiceProvider::class);
Then in app\Providers\AppServiceProvider.php, update register method to add:
public function register()
{
$this->app->singleton('Illuminate\Contracts\Routing\ResponseFactory', function ($app) {
return new \Illuminate\Routing\ResponseFactory(
$app['Illuminate\Contracts\View\Factory'],
$app['Illuminate\Routing\Redirector']
);
});
}
The response helper may be used to conveniently generate other types of response instances. When the response helper is called without arguments, an implementation of the Laravel\Lumen\Http\ResponseFactory class is returned.
use Laravel\Lumen\Http\ResponseFactory;
Try like this
public function register() { $this->app->singleton(\Illuminate\Contracts\Routing\ResponseFactory::class, function() { return new \Laravel\Lumen\Http\ResponseFactory(); }); $this->app->bind(\Illuminate\Contracts\Routing\UrlGenerator::class, function ($app) { return new \Laravel\Lumen\Routing\UrlGenerator($app); }); }
call
use Tests\TestCase;
instead of
use PHPUnit\Framework\TestCase;
your function depends on another function, So you should extend like feature test and not unit tests.
Those who are still getting routing related error, just put the following line in your composer.json file and run the command composer update
"illuminate/routing": "^5.6"
composer update
and boom here we go, wish all things are working great now
https://stackoverflow.com/a/48678862/9751944
#sunben's answer worked for me but I added the following inside the register method
$this->app->bind(\Illuminate\Routing\RouteCollectionInterface::class, function ($app) { return new \Illuminate\Routing\RouteCollection; });