Browserify cannot find npm module - reactjs

I'm trying to create an NPM module with great pain: react-smallgrid
import React from 'react';
import _ from 'lodash';
export default class SmallGrid extends React.Component{
Compiled with:
browserify: {
options: {
transform: [
['babelify', {
presets: ['react', 'es2015']
}]
]
},
jsx: {
files: {
'./dist/js/smallgrid.js': [
'./src/smallgrid.jsx',
]
}
},
When I import the js file in another project/jsx and try to browserify that, it gives the error:
Error: Cannot find module './ReactMount' from '/Users/me/code/react-smallgrid/dist/js'
I thought it's already compiled for use? I don't understand this.
Meanwhile
I've tried building it with webpack, which gives the following output:
> webpack -p
Hash: 00fd87c95d39230bd485
Version: webpack 1.12.11
Time: 14002ms
Asset Size Chunks Chunk Names
smallgrid.js 248 kB 0 [emitted] smallgrid
+ 160 hidden modules
WARNING in smallgrid.js from UglifyJs
Condition always true [./~/react/lib/ReactMount.js:764,0]
Condition always true [./~/react/lib/findDOMNode.js:46,0]
Condition always true [./~/react/lib/instantiateReactComponent.js:80,0]
Still does not work.

You need to make React libs available to your code.
Run this to add browserify-shim:
npm i browserify-shim -D
Add this to your package.json:
"browserify": {
"transform": [
"browserify-shim"
]
},
"browser": {
"react": "./node_modules/react/dist/react.js",
"react-dom": "./node_modules/react-dom/dist/react-dom.js",
"lodash": "./node_modules/lodash"
},
"browserify-shim": {
"./node_modules/react/dist/react.js": "React",
"./node_modules/react-dom/dist/react-dom.js": "ReactDOM",
"./node_modules/lodash": "lodash"
}
By the way, you can also use browserify externals in your config to further reduce the resulting package. It's best to not include for example: React in your bundle.
Note:
I also sent you a PR in Github for the solution.

Your problem appears to be that you are providing the transpiled code as your library. The transpiled code includes ReactMount internally. You should be providing the source code for use as a library. Then it will transpile correctly with browserify. Look at any other npm libraries and I think you will see they provide the source to use in your imports.
As you indicated in your comment. #madox2 in Cannot import ES2015 module replied with;
"scripts": {
"compile": "babel --presets es2015,stage-0 -d dist/js/ src/"
}
So, npm install -g babel babel-preset-es2015 babel-preset-stage-0. Then npm run compile. That should put your transpiled code into dist/js.

Related

Babel 7 - Uncaught ReferenceError: regeneratorRuntime is not defined

I'm getting the error Uncaught ReferenceError: regeneratorRuntime is not defined using React with webpack and Babel .
I've followed this answer by defining my .babel.rc as:
{
"presets": ["#babel/preset-env", "#babel/preset-react"] ,
"plugins": [
["#babel/plugin-transform-runtime"]
]
}
and running:
npm i --save-dev #babel/plugin-transform-runtime
However, I get the exact same error afterwards. I've also followed this other answer and this one, but still get the exact same error.
My babel specific installations in package.json are as follows:
"dependencies": {
"#babel/runtime": "^7.14.6"
},
"devDependencies": {
"#babel/core": "^7.14.6",
"#babel/plugin-transform-runtime": "^7.14.5",
"#babel/preset-env": "^7.14.7",
"#babel/preset-react": "^7.14.5"
}
Any ideas?
hey I ran into the same problem and I am using Babel 7, for me I installed these two dependencies:
npm install --save #babel/runtime
npm install --save-dev #babel/plugin-transform-runtime
And, in .babelrc, add:
{
"presets": ["#babel/preset-env"],
"plugins": [
["#babel/transform-runtime"]
]
}
and this solved my problem
{ "presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "9.2.1"
}
}
],
"#babel/preset-react" ] }
This is my file .babelrc
Look:
#babel/preset-env is a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s). This both makes your life easier and JavaScript bundles smaller!
your problemes:
You are using "# babel / preset-env" you must specify the version of node to compile. "node> 7.6". I recommend 10.
Why node > 7.6 Node.js 7.6 has shipped with official support for async/await enabled by default and better performance on low-memory devices.
How do you specify the version: It's simple
targets.node
string | "current".
If you want to compile against the current node version, you can specify "node": "current", which would be the same as "node": process.versions.node.
AND FOR ME LOOK LIKE THIS:
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "9.2.1"
}
}
],
"#babel/preset-react"
]
}
This allows the compiler to understand ASYNC AWAIT, hope it helps you!
You can also add a plugin to handle your "asyc away"
https://babeljs.io/docs/en/babel-plugin-transform-async-to-generator
ATTENTION - > This Config is for node-js; it is just a example
This ended up working for me:
How to allow async functions in React + Babel?
My problem was that I was defining the babel plugin in both my .babel.rc file and my webpack.config.js file. I needed to remove that plugin from my webpack.config.js and simply use it only in my .babel.rc file. Then it worked well.

Typescript + Parcel new JSX transform - React is not defined error

I've updated to React 17+ and am now getting a React is not defined issue when removing
import React from 'react' statements from typescript TSX and JSX files.
How can I fix this?
I've identified the problem is the version of a few babel plugins that are outdated that Parcel (version 2.0.0-beta.3.1 at time of writing) is using.
Here's my solution:
Add these two packages to you package.json file:
yarn add --dev #babel/core #babel/plugin-transform-react-jsx
or
npm i -D #babel/core #babel/plugin-transform-react-jsx
update your babel config or create a new .babelrc file:
{
"plugins": [
[
"#babel/plugin-transform-react-jsx",
{
"runtime": "automatic"
}
]
]
}

How to resolve "Cannot use import statement outside a module" in jest

I have a React application (not using Create React App) built using TypeScript, Jest, Webpack, and Babel. When trying to run yarn jest, I get the following error:
I have tried removing all packages and re-adding them. It does not resolve this. I have looked at similar questions and documentation and I am still misunderstanding something. I went so far as to follow another guide for setting up this environment from scratch and still received this issue with my code.
Dependencies include...
"dependencies": {
"#babel/plugin-transform-runtime": "^7.6.2",
"#babel/polyfill": "^7.6.0",
"babel-jest": "^24.9.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-test-renderer": "^16.11.0",
"source-map-loader": "^0.2.4"
},
"devDependencies": {
"#babel/core": "^7.6.0",
"#babel/preset-env": "^7.6.0",
"#babel/preset-react": "^7.0.0",
"#types/enzyme": "^3.9.2",
"#types/enzyme-adapter-react-16": "^1.0.5",
"#types/jest": "^24.0.13",
The component's import lines...
import * as React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/pages";
import {
Footer,
Header,
Navigation,
} from "./components/shared";
The test file....
import * as React from "react";
import * as renderer from "react-test-renderer";
import App from "../App";
it("Renders the Footer correctly", () => {
const tree = renderer
.create(<App />)
.toJSON();
expect(tree).toMatchSnapshot();
});
I expected to be able to use named imports in my components without my tests blowing up. It appears to fix the issue if I only use default imports through my solution, but I would prefer to not go that route.
Also using Babel, Typescript and Jest. Had the same failure, driving me crazy for hours.
Ended up creating a new babel.config.js file specifically for the tests. Had a large .babelrc that wasn't getting picked up by jest no matter what i did to it. Main app still uses the .babelrc as this overrides babel.config.js files.
Install jest, ts-jest and babel-jest:
npm i jest ts-jest babel-jest
babel.config.js (only used by jest)
module.exports = {presets: ['#babel/preset-env']}
jest.config.js
module.exports = {
preset: 'ts-jest',
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
"^.+\\.(js|jsx)$": "babel-jest",
}
};
package.json
"scripts": {
"test": "jest"
Use Babel to transpile those JS Modules and you'll be able to write your tests with es6.
Install Babel/preset-env
npm i -D #babel/preset-env
Create a babel configuration file with the preset
//babel.config.js
module.exports = {presets: ['#babel/preset-env']}
I solved this by migrating the .babelrc file to babel.config.js! Shocker.
For future references,
I solved the problem by using below jest config, after reading Logan Shoemaker's answer.
module.exports = {
verbose: true,
setupFilesAfterEnv: ["<rootDir>src/setupTests.ts"],
moduleFileExtensions: ["js", "jsx", "ts", "tsx"],
moduleDirectories: ["node_modules", "src"],
moduleNameMapper: {
"\\.(css|less|scss)$": "identity-obj-proxy"
},
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
"^.+\\.(js|jsx)$": "babel-jest",
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/file.js",
}
};
try this thing if you are using babel 6
Adding #babel/plugin-transform-modules-commonjs in the plugin section of babel.config.js
or
For my case import issue was due to the react file drop by adding that to transformIgnorePatterns
"transformIgnorePatterns": ["/node_modules/(?!react-file-drop)"]
I fixed it by simply appending the pattern after the run statement in package.json runner
{
"scripts": {
...
"test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!my-library-dir)/'"
...
Then, just run npm test
Solution: my named imports were coming from index.js files and I believe ts-jest needed them as index.ts files (I'm using Typescript). If anyone else runs into this error, couldn't hurt to check if you derped your file extensions.
I wasted a lot of time on this, unfortunately, but I learned a lot about webpack configurations and Babel.
Add your test script in package.json with Node experimental feature: --experimental-vm-modules
In this way you won't require babel or other dependencies.
Examples:
"test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node' jest"
If you get this error: zsh: command not found: jest, try with node passing jest.js like this:
"test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node --trace-warnings' node node_modules/jest/bin/jest.js --detectOpenHandles"
I'm surprised that none of the answers does not give an elegant solution:
jest.config.js
module.exports = {
...,
globals: {
"ts-jest": {
isolatedModules: true,
},
},
};
This compiles each file separately therefore avoiding the no exports issue.
Create .babelrc on the main directory and add this code and install these packages
#babel/core, #babel/preset-env and #babel/preset-react
{
"presets": [
[
"#babel/preset-env",
{
"modules": "commonjs"
}
],
"#babel/preset-react"
]
}
Matching file extensions:
I importing a file named Todo.jsx in the root as ./src/Todo/. Whenever I changed it to Todo.js the problem went away.
Disclaimer: I'm not sure what the requirement is for having your file extension as jsx vs js for your components. It did not effect me at all, but I could imagine it could mess with intellisense or snippets.
For me renaming file to babel.config.js worked.
Here is my config file an NX project using next with Typescript along with Twin-macro
// .babelrc.js >> babel.config.js
module.exports = {
presets: [
[
"#nrwl/react/babel",
{
"runtime": "automatic",
"targets": {
"browsers": [">0.25%", "not dead"]
},
"preset-react": {
runtime: "automatic",
importSource: "#emotion/react",
},
}
],
'#babel/preset-env',
'#emotion/babel-preset-css-prop',
'#babel/preset-typescript'
],
plugins: ['#emotion', 'macros', '#babel/plugin-transform-runtime', 'react-docgen'],
}
Also, please note even updating package.json works,
https://kulshekhar.github.io/ts-jest/docs/getting-started/presets/#basic-usage
// package.json
"jest": {
// Replace `ts-jest` with the preset you want to use
// from the above list
"preset": "ts-jest"
}
I encountered the same problem with Typescript, Jest, and VueJS/VueCli 3. The normal build has no problem. only happens for Jest. I struggled for hours by searching. But no answer actually works. In my case, I have a dependency on my own typescript package which I specific "target": "es6" in the tsconfig.json. That's the root cause. So the solution is simply to change the dependent's (Not the same project) back to es5 tsconfig.json:
{
"compilerOptions": {
"target": "es5",
...
},
...
}
Personnaly I followed #ajwl setup but discovered that jsdom-worker inside setupFiles: section of jest.config.js was triggering that same error. Once removed, my tests were passing.
P.S. my babel.config.js is a bit different, since I have a Vuejs (v2) SPA (bundled with Vitejs):
module.exports = {
plugins: ['#babel/plugin-transform-modules-commonjs'],
presets: [['#babel/preset-env', { targets: { node: 'current' } }]]
}
The problem is likely that jest doesn't support esmodules natively. Which can cause problems if youre typescript target is es6 or greater.
If you are testing the built typescript output, you could simply add a module=commonjs flag while transpiling. That way, your code can run with es6 or greater and still work with Jest.
"scripts": {
"test": tsc --module commonjs && jest {your-output-folder}/
}
What's great about this is that I didn't have to add any additional babel dependencies or special jest runners :)
I solved it by changing my tsconfig.json to a compatible native output
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
It is not ideal in every scenario but you might be okay with this.
All I had to do, was simply updating the package #babel/preset-env in the dev dependencies to the latest version
// package.json
"#babel/preset-env": "^7.18.6"
None of the answers helped me, what did help me was making sure my NODE_ENV was set to test, since babel config is per NODE_ENV using the wrong NODE_ENV by accident that is not configured in babel config will mean you wont be using babel and the typescript files will not be transformed.
It took me couple of hours to figure this one out so i hope it will save someone else the time it took me.
Don't know why and how but how I solved the problem was really interesting.
Just add __mocks__ folder in your src folder and create an empty file inside __mocks__ named axios.js
I discovered that this error might be triggered when you try to load a dependency that is made for the browser and, thus, cannot work with jest (node).
I had a lot of trouble solving this issue for #zip.js/zip.js lib. But I could do it like that:
Here is my jest.config.js. Adapt it to your need. The trick here is the moduleNameMapper that will make all imports to zip.js point to the file __mocks__/#zip.js/zip.js I created in my root folder.
export default {
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper: {
'#zip.js/zip.js': '<rootDir>/__mocks__/#zip.js/zip.js',
},
}
And here is what I have in <rootDir>/__mocks__/#zip.js/zip.js file:
module.exports = {}
Too late for this answer :)
After trying all the possible solutions, this worked for me:
The solution, that works for me:
create a file named jest/mocks/#react-native-firebase/crashlytics.js
export default () => ({ log: jest.fn(), recordError: jest.fn(), });
create a file named jest/jestSetupFile.js
import mockFirebaseCrashlytics from './mocks/#react-native-firebase/crashlytics';
jest.mock('#react-native-firebase/crashlytics', () => mockFirebaseCrashlytics);
in package.json add
"jest": { "setupFiles": ["./jest/jestSetupFile.js"] },
I needed to do a couple things to get this to work for me
Rename my .babelrc to babel.config.js and make a little change:
// .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"corejs": "3.26",
"useBuiltIns": "usage"
}
],
"#babel/preset-react"
],
...
}
// babel.config.js - This still works fine with webpack
module.exports = {
"presets": [
[
"#babel/preset-env",
{
"corejs": "3.26",
"useBuiltIns": "usage"
}
],
"#babel/preset-react"
],
...
}
Add the following to my jest config file:
{
...
"transformIgnorePatterns": [
"node_modules/(?!(react-leaflet-custom-control)/)"
],
...
}
Where react-leaflet-custom-control was the package causing issues for me.
If you're using TypeScript, and you have a tsconfig.json file, try removing "module": "esnext" if you're using it
Running npm ci fixed this problem for me.

How to avoid using relative path imports (/../../../redux/action/action1) in create-react-app

I've been using create-react-app package for creating a react website. I was using relative paths throughout my app for importing components, resources, redux etc. eg, import action from '../../../redux/action
I have tried using module-alis npm package but with no success. Is there any plugin that I can use to import based on the folder name or alias i.e. an absolute path?
Eg., import action from '#redux/action' or import action from '#resource/css/style.css'
Create a file called .env in the project root and write there:
NODE_PATH=src
Then restart the development server. You should be able to import anything inside src without relative paths.
Note I would not recommend calling your folder src/redux because now it is confusing whether redux import refers to your app or the library. Instead you can call your folder src/app and import things from app/....
We intentionally don't support custom syntax like #redux because it's not compatible with Node resolution algorithm.
The approach in the accepted answer has now been superseded. Create React App now has a different way to set absolute paths as documented here.
To summarise, you can configure your application to support importing modules using absolute paths by doing the following:
Create/Edit your jsconfig.json/tsconfig.json in the root of your project with the following:
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
Once you have done this you can then import by specifying subdirectories of "src" (in the following example, components is a subdirectory of src) e.g.
import Button from 'components/Button'
We can use webpack 2 resolve property in the webpack config.
Sample webpack config using resolve :
Here component and utils are independent folder containing React components.
resolve: {
modules: ['src/scripts', 'node_modules'],
extensions: ['.jsx', '.js'],
unsafeCache: true,
alias: {
components: path.resolve(__dirname, 'src', 'scripts', 'components'),
utils: path.resolve(__dirname, 'src', 'scripts', 'utils'),
}
}
After that we can import directly in files :
import UiUtils from 'utils/UiUtils';
import TabContent from 'components/TabContent';
Webpack 2 Resolve Reference
After you try Ben Smith's solution above if you find eslint complains about importing absolute path add the following line to your eslint config:
settings: {
'import/resolver': {
node: {
paths: ['src'],
},
},
},
replace 'src' with your folder if you use your own boilerplate with your folder's name.
Feb 2010
Wasted about an hour on this.
An example is below:
Goal: Import App.css in HomePage.js
myapp\src\App.css
myapp\src\pages\HomePage.js
File: jsconfig.json
{
"compilerOptions": {
"baseUrl": "src"
}
}
File: src\pages\HomePage.js
import "App.css";
The alias solution for craco or rewired create-react-app is react-app-alias for systems as: craco, react-app-rewired, customize-cra
According docs of mentioned systems replace react-scripts in package.json and configure next:
react-app-rewired
// config-overrides.js
const {aliasWebpack, aliasJest} = require('react-app-alias')
const options = {} // default is empty for most cases
module.exports = aliasWebpack(options)
module.exports.jest = aliasJest(options)
craco
// craco.config.js
const {CracoAliasPlugin} = require('react-app-alias')
module.exports = {
plugins: [
{
plugin: CracoAliasPlugin,
options: {}
}
]
}
all
Configure aliases in json like this:
// tsconfig.paths.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"example/*": ["example/src/*"],
"#library/*": ["library/src/*"]
}
}
}
And add this file in extends section of main typescript config file:
// tsconfig.json
{
"extends": "./tsconfig.paths.json",
// ...
}
I am using babel-plugin-module-resolver for my project to resolve that problem.
babel-plugin-module-resolver also is the same as module-alis. So I think you should just resolve using module-alis problem.
Because you didn't tell us why using module-alis was fail? So i cant show you how to fix it.
Dont give up your solution while you dont know the reason!
in package.json file,
eject this code in the scripts object like this..
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js --env=jsdom",
"eject": "NODE_PATH=src/ react-scripts eject"
},
this will enable the absolute path imports in your app
None of the answers worked for me. Some didn't work at all and others worked but the import was already inside src, for example:
import something from 'path/to/file'.
Whereas I wanted to be able to do:
import something from 'src/path/to/file'
Here is how I solved it:
tsconfig.json
{
"compilerOptions": {
// ...
"baseUrl": ".",
"rootDirs": [
"src"
]
},
"include": [
"src"
]
}

Jest not preprocessing my JSX

I am following the Jest tutorial to test a react component and am running into preprocessing issues with my jsx. I assume the error is due to preprocessing, the error message is not very helpful. Googling shows similar errors with older versions of react/jest that were fixed by including the /** #jsx React.DOM */ docblock which as far as I can tell was fixed.
When I run my test:
Using Jest CLI v0.8.0, jasmine1
FAIL spec/MyComponent_spec.js
Runtime Error
SyntaxError: /Users/asdf/react/stuff-react/spec/MyComponent_spec.js: Unexpected token (13:6)
npm ERR! Test failed. See above for more details.
The line in question is the one that should be rendering my component:
jest.dontMock('../src/MyComponent');
let React = require('react');
let ReactDOM = require('react-dom');
let TestUtils = require('react-addons-test-utils');
const MyComponent = require('../src/MyComponent');
describe('MyComponent', function(){
it('render', function(){
var myComponent = TestUtils.renderIntoDocument(
// This is the line referenced in the test error
<MyComponent />
)
var myComponentNode = ReactDOM.findDOMNode(myComponent);
expect(myComponentNode.textContent).toEqual('hi');
});
});
I thought my package.json was responsible for telling jest to preprocess that file?
"scripts": {
"test": "jest"
},
"jest": {
"testDirectoryName": "spec",
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils",
"<rootDir>/node_modules/fbjs"
]
},
My component:
import React from 'react';
class MyComponent extends React.Component({
render () {
return (
<div>
hi
</div>
)
}
});
export default MyComponent;
Using a .bablerc file in the project root directory fixed it for me.
I was not using a .babelrc file while developing because I defined my presets in the webpack configuration file. But it turns out that when you run the unit test with jest, then jest is not aware of this presets as it does not know about webpack. So simply adding a .babelrc file with the presets should solve the issue for you too.
Contents of .babelrc:
{
"presets": ["es2015", "react"]
}
I had a similar problem, and the solution was adding this to jest config file:
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.jsx$": "babel-jest" // This line was missing
}
The reason it was needed in our project, is because we overridden the default "transform" value in jest config file.
I think you may just need to add the testFileExtensions and testFileExtensions to the jest section of your package.json.
See the README.md of babel-jest:
https://github.com/babel/babel-jest
Changing my .babelrc config file to babel.config.js or babel.config.json worked for me because Jest ignores .babelrc.
Add ["#babel/preset-react", { runtime: "automatic" }] to the presets in babel.config.js.
Your babel.config.js file should look something like:
module.exports = {
presets: [
["#babel/preset-env", { targets: { node: "current" } }],
"#babel/preset-typescript",
["#babel/preset-react", { runtime: "automatic" }],
],
};
And you need to set your jest environment to jsdom by adding this to the top of your test (make sure you've installed the jest-environment-jsdom node package):
/**
* #jest-environment jsdom
*/

Resources