CRA and bundle-loader - javascript

I am trying to use react-router with code splitting inside my create-react-app application.
import loadSettings from 'bundle-loader?lazy!./Settings';
This line gets my an error:
Line 5: Unexpected '!' in 'bundle-loader?lazy!./Settings'. Do not use import syntax to configure webpack loaders import/no-webpack-loader-syntax
I assume this is because of some es-lint settings. How can I disable it so I can use webpack bundle-loader inside my CRA application?

I somehow managed to solve this.
What I did is:
Eject the creact-react-app by running npm run eject
Modify the package.json file by adding a rules key to the eslintConfig so it looks like this:
"eslintConfig": {
"extends": "react-app", // This was already in the file
"rules": {
"import/no-webpack-loader-syntax": 0
}
}
Set your components like described in the docs.
Hope this helps someone, as I have digged through many forums without finding the right answer!
BTW support for code splitting with dynamic import should be coming to CRA soon!

Related

Solve having more than one copy of React in the same app

I'm developing a React module locally. For that, I'm linking my module using npm link.
The module is imported successfully but hooks are failing inside the module. It's throwing the following error:
Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following
reasons: 1. You might have mismatching versions of React and the
renderer (such as React DOM) 2. You might be breaking the Rules of
Hooks 3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to
debug and fix this problem.
Checking the suggestions at React docs, I can confirm my app is using duplicate versions of React since the following code returns false:
// node_modules/mymodule/src/index.js
export { default as ReactFromModule } from 'react'
// src/index.js
import React from 'react'
import { ReactFromModule } from 'mymodule'
console.log(React === ReactFromModule) //false
This issue is full of suggestions but they are confusing. How can I solve it?
Note: Im not breaking rules of hooks, the error appears only when importing the module from an application.
In the module you are developing, add the conflicting packages to peerDependencies (and remove them from dependencies or devDependencies):
// package.json
"peerDependencies": {
"react": "16.13.1",
"react-dom": "16.13.1"
},
Execute npm install in your module.
Now add react and react-dom to the webpack configuration of your module as externals. These packages shouldnt be included in the bundle of the module (the app that uses the module will provide them):
// webpack.config.js
module.exports = {
/*
rest of config...
*/
output: {
filename: "index.js",
pathinfo: false,
libraryTarget: 'umd', // In my case, I use libraryTarget as 'umd'. Not sure if relevant
},
externals: {
// Use external version of React
"react": {
"commonjs": "react",
"commonjs2": "react",
"amd": "react",
"root": "React"
},
"react-dom": {
"commonjs": "react-dom",
"commonjs2": "react-dom",
"amd": "react-dom",
"root": "ReactDOM"
}
},
};
Then, after building your module, in your application you can check that both versions are now the same:
// node_modules/mymodule/src/index.js
export { default as ReactFromModule } from 'react'
// src/index.js
import React from 'react'
import { ReactFromModule } from 'mymodule'
console.log(React === ReactFromModule) // true :)
Adding react and react-dom as peerDependencies in the package.json didn't work for me.
I had to add an alias to the webpack configuration file:
// webpack.config.js
resolve: {
alias: {
react: path.resolve('./node_modules/react'),
}
In response to another comment, merely moving React to peerDependencies does not adequately resolve the issue in all cases. I would reply to that comment directly, but StackOverflow requires more reputation to respond to wrong answers than it does to post them.
I have a shared React component module built using Webpack and have run into the same issue. I've outlined one possible fix in this comment below which requires modifying peerDependencies and using npm link in a fashion similar to the answer shared by mtkopone.
https://github.com/facebook/react/issues/13991#issuecomment-841509933
My solution is a bit hacky and I wouldn't recommend it for long-term use. If you are using Webpack (which you tagged this question as), this article may detail a more permanent solution (https://medium.com/codex/duplicate-copy-of-react-errors-when-using-npm-link-e5011de0995d). I haven't tried it yet, but the author seems to have tried all the (incorrect) solutions out there and is also running into the hooks issue while trying to build shared component libraries.
The author of that article is trying to debug a Create-React-App app. While CRA uses webpack under the hood, you can't access the webpack.config directly, so the author has to perform some workarounds to do so. If you aren't using CRA, but just plain Webpack, then you could consider using the resolve.alias section of webpack.config to ensure there are no duplicate copies of React (see: https://blog.maximeheckel.com/posts/duplicate-dependencies-npm-link/)
I was attempting to use the peerDependencies and removal of the devDependencies and it was failing.
It turned out I had a node_modules folder in one of the parent folders of the library I was working on and the duplicate version of React was being loaded from there instead of the tool that was trying to use the React library.
Rather than editing the devDependencies to remove react I just wrote a small script to delete anything that's in the peerDependencies from the node_modules folder.
npm view --json=true . peerDependencies | jq -r 'keys | .[] | #text' | while read dep; do rm -r ./node_modules/${dep} && echo Removed ${dep}; done
In my case I was also missing import React from 'react' from couple of files.
check this

Can't find module or its corresponding type declarations when trying to import SDK in Angular Project

Currently attempting to use an SDK in an existing Angular project and we are unable to find the cause to the following problem.
Here is an image of the error:
Cannot find module 'flux-sdk' or its corresponding type declarations
After doing some digging we found various post with the same issue and have tried just about everything we could find and are still unable to solve the error.
Steps...
npm install --save flux-sdk;
import Flux from 'flux-sdk';
Fails on import ( Step 2 ) with the error shown above.
We are not sure why this is happening and because we have tried the other solutions found online and unable to solve the issue I come here.
I think you could achieve adding typing for a package which doesn't have type definition like this package flux-sdk in an Angular project by following steps:
Create a typings directory at the root level then create the typing for this package which is likely called flux-sdk.d.ts:
typings/flux-sdk.d.ts:
declare module 'flux-sdk' {
const flux: any; // you can define whatever is now exported
export default flux;
}
Then just include typings in your tsconfig.json:
{
"compilerOptions": {
// ...
},
"include": [
"typings"
],
}
Kindly try these solutions.
Method 1:
Simply use require instead of import.
// import { Flux } from 'flux-sdk'
const Flux = require('flux-sdk');
Method 2:
Try to replace these line in the tsconfig.json if you want use import
"noImplicitAny": false,
"allowJs": true,
I hope they would help you, thanks.
Maybe you use old package-lock.json. Please delete package-lock.json&node_modules and reinstall node modules.

SyntaxError with Jest and React importing SCSS files

I am testing using Jest and my appication is running on Next.js... I am trying to test a page component in my Next application, but I am receiving errors that are shown in the following screenshot; The "Before" image is before I tried implementing a solution found on Stackoverflow, and the "After" is after the solution was implemented. I am still stuck and need some friendly help!
Here is also my current Jest config in my package.json
"jest": {
"setupFiles": ["./shim.js", "./setupTests.js"],
"verbose": true,
"moduleNameMapper": {
"^.+\\.(css|scss)$": "./cssStub.js"
}
}
Thanks!
I'm using CSS modules and it convenient for me to use "proxy" as if the code requires styles, jest will return a proxy, that will return the required field name instead of the value.
For example:
import * as styles from './styles.scss';
console.log(styles.someClassName);
// the proxy in that case will return a string with `someClassName` value.
All you need to configure is install
npm install --save-dev identity-obj-proxy
and add
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy",
}
to your Jest section in the package.json file.
Edit
Pay attention that according to the docs you should use <rootDir>
when you are mapping to a file.
"\\.(css|scss)$": "<rootDir>/cssStub.js.js",
My issue was silly enough that I wrongly specified my <rootDir> path. I would suggest reading the solution from this post for further details to how to resolve similar issue... Thanks all for the help!
SyntaxError with Jest and React and importing CSS files

People ask for the # character in import form '#' in nodejs or vuejs [duplicate]

For example:
import Component from '#/components/component'
In the code I'm looking at it behaves like ../ going up one level in the directory relative to the file path, but I'd like to know more generally what it does. Unfortunately I can't find any documentation online due to the symbol searching problem.
The meaning and structure of the module identifier depends on the module loader or module bundler. The module loader is not part of the ECMAScript spec. From a JavaScript language perspective, the module identifier is completely opaque. So it really depends on which module loader/bundler you are using.
You most likely have something like babel-plugin-root-import in your webpack/babel config.
Basically it means from the root of the project.. it avoids having to write things like import Component from '../../../../components/component'
Edit: One reason it exists is because import Component from 'components/component' doesn't do that but instead search in the node_modules folder
Know it's old, but I wasn't exactly sure how it's defined, so looked it up, came by, dug a little deeper and finally found this in my Vue-CLI (Vue.js) generated Webpack config
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'#': path.join(__dirname, '..', dir)
}
},
so it's an alias which in this case points to the root of vue-cli generated src directory of the project
Update: As correctly mentioned by #aderchox in the comments, this is a general Webpack feature and not limited to Vue
To make Ben's answer more comprehensive:
First you need to add babel-plugin-root-import in your devDependencies in package.json (If using yarn: yarn add babel-plugin-root-import --dev).
Then in your .babelrc add the following lines into plugins key:
"plugins": [
[
"babel-plugin-root-import",
{
"rootPathPrefix": "#"
}
]
]
Now, you can use #. For example:
Instead of
import xx from '../../utils/somefile'
You Can
import xx from '#/utils/somefile'
As said above, this feature is not in JS by default. You have to use a babel plugin to enjoy it. And its job is simple. It allows you to specify a default root source for your JS files and helps you map your file imports to it.
To get started install through either npm:
npm install babel-plugin-root-import --save-dev
or
yarn add babel-plugin-root-import --dev
Create a .babelrc in the root of your app and configure these settings to your taste:
{
"plugins": [
["babel-plugin-root-import", {
"rootPathSuffix": "the-preferred/root/of-all-your/js/files",
"rootPathPrefix": "#"
}]
]
}
With the config above, you can simply import from that source like:
import Myfile from "#/Myfile"
without doing all this funky stuff:
"/../../../Myfile"
Note that you can also change the symbol to anything like "~" if that floats your boat.
I am using VS code to build react native Apps.
What you need is:
create a jsconfig.json under root path of your App
in your jsconfig.json, add the following code:
{
"compilerOptions": {
"baseUrl": ".",
"target": "ES6",
"module": "commonjs",
"paths": {
"#/*": ["src/*"],
"#components/*": ["src/components/*"],
"#core/*": ["src/core/*"]
}
},
"exclude": ["node_modules"]
}
basically like "shortcut" : ["abs_path"]
In case you are using Typescript, you could achieve this by simply using your tsconfig.json like this:
{
"compilerOptions": {
...
"baseUrl": ".",
"paths": {
"#lib/*": ["app/lib/*"]
}
},
}
// # is an alias to /src
Inspired by Can Rau's answer I made a similar discovery in my src/views/Home.vue file. This file was created with the latest (July 2021, Ubuntu 20.04) versions: npx #vue/cli create myfirstvue --default.
I "inferred" it was /src but wanted to know why, because Ben's accepted answer said it would be the root of my project, which in fact is the parent, of /src.
Here is Home.vue:
...
<script>
// # is an alias to /src
import HelloWorld from '#/components/HelloWorld.vue'
</script>
It is defined by Vue Webpack template, which I learned from this other SO answer.
It is a way of remapping module paths, not part of the ES itself, you have to use babel import feature.

How to create aurelia typescript project with vs2017rc

I am new to aurelia, and I need create a prototype project of the framework. At the beginning, I planed to use skeleton-typescript-aspnetcore skeleton, but when I tried the vs2017rc, I found it uses .csproj as the default format(while vs2015 is project.json/.xproj), I think we should follow the vs2017 because we will upgrade our IDE after it's been launched.
The vs2017 have a wizard to upgrade .xproj project, but after the upgrading(skeleton-typescript-aspnetcore), there still lots of error ahead me...
I also tried aurelia-cli, but seems it has not support vs2017 yet, does anyone could give a guide to create the prototype project? I will integrate some plugins like the skeleton mentioned above, such as gulp,karma,breeze...
thank you in advance.
Since Visual Studio 2017 just launched I thought I'd answer how I solved this, as there are still many errors when using "skeleton-typescript-aspnetcore".
Using https://github.com/aurelia/skeleton-navigation/releases/tag/1.1.2 as a starting point, these are the steps to get it running:
When you first run the project you will get errors complaining that some files located in /test/ is not under 'rootDir'. In your tsconfig.json the rootDir is defined as "src/", this can be solved simply by moving your test folder inside your src folder. This will cause new errors because the paths defined in those files has now changed. You will need to edit app, child-router and users imports like this:
import {Users} from '../../users'; IntelliSense should help you out here.
The command gulp test will also not run before changing to the new path, you can change the path in karma.conf.js:
files: [
'src/test/unit/setup.ts',
'src/test/unit/*.ts'
],
Next the file users.ts will throw errors like Type 'Response' is not assignable to type 'any[]'. You will need to tell TypeScript what you're declaring like this: public users : Object = []; or simply: public users = {};
The final problem is that you're going to have a lot of duplicate identifier errors, at the time of writing this the cause of this seems to be from the changes brought on by TypeScript version 2.2.1. I don't know what specifically breaks, but I know that previous version 2.1.5 still works. So what you need to do is to run npm install typescript#2.1.5 --save in your src/skeleton directory, the --save is just to update your package.json file, you can do this on your own later as well if you wish.
After you've done that your gulp errors (20~ of them) should be resolved. But there are still some errors remaining caused by duplicate signatures. Again, things have changed in TypeScript 2.0+, there is now a simplified way of getting and using declaration files. Here is an answer on SO on how to use the #types feature: How should I use #types with TypeScript 2 , but to keep this short and sweet you will have to go to your tsconfig.json file and explicitly tell where to find the #types/node folder. It would look something like this:
"compilerOptions": {
...
"typeRoots": [
"node_modules/#types"
],
"types": [ "node" ]
...
},
Hope this helps, with these changes the project should now build and launch correctly.
EDIT:
I recently ran into some problems again with building my project. I got a lot of duplicate identifiers again... I however ran across this answer on SO: TypeScript throws multiple duplicate identifiers
Apparently TypeScript latest ships with fetch definitions out of the box, so I was able to run the command from the answer in the link:
npm uninstall #types/whatwg-fetch
And upgrading from typescript 2.1.5 to latest:
npm install typescript --save
You might even want to install typescript globally by appending -g.
Also this will continue to be an issue unless you comment out/delete url and whatwg-fetch from typings.json globalDependencies in order to prevent it from recreating itself:
"globalDependencies": {
//"url": "github:aurelia/fetch-client/doc/url.d.ts#bbe0777ef710d889a05759a65fa2c9c3865fc618",
//"whatwg-fetch": "registry:dt/whatwg-fetch#0.0.0+20160524142046"
}
Then you can either delete the typings folder, running typings install again or edit index.d.ts in the typings folder and delete the reference paths to whatwg-fetch and url.
Hope this helps someone who might've encountered the same problems even after "fixing" it.

Categories

Resources