I have a parent repository developed with React, and I have a child Sub Module inside of it(which is developed by react too):
The project folder structure is something like below:
parent
/.git
/nodemodule
/src
/subModules/childProject
/.git
/src
/js
/x.jsx // i want this file from parent project
/...
/...
I want to access and use the x.jsx component from parent project. I imported it like blow in my parent project:
import X from '../subModules/childProject/src/js/x.jsx'
but it gives me unexpected token!
7 | return (
> 8 | <article className="center">
| ^
9 | this is test global component with in child Project
10 | </article>
11 | )
it looks like that it cannot transform it because I wrote just a test function in old JavaScript way like:
export default function test(x) {
return x * 2
}
It imported without any error and works but when I wrote function in arrow style like below:
export default function test(x) => x * 2
it does not work. It seems like it's just a runtime error of transpiling modules, how can I transpile and import react components from child submodule in to parent repository?
The problem was that Babel does not know that there is a submodule project in the root of the project, just by changing my .babelrc file to babel.config.js and configuring it by babelrcRoots I would be able to solve the issue:
Now my babel.config.js file looks like this:
module.exports = {
"presets": [
"#babel/preset-react",
"#babel/preset-env"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-object-rest-spread"
],
"babelrcRoots": [ "./", "./subModules/someFolder" ]
}
Now I can import any react component and JS modules from sub-repository in side my parent project and it works correctly.
Related
EDIT: Unfortunately this seems like a known issue that cannot be solved without messing with create-react-app, although I could be wrong :( https://github.com/facebook/create-react-app/issues/3547#issuecomment-593764097
I am working on a react project using typescript and firebase functions, with my firebase functions project folder inside the project folder for the react app. As there are lots of enums and interfaces that I want to keep consistent between my frontend (the react app) and my backend (the firebase functions), I use a symlink to share a folder containing files common between these two projects. This works fine with interfaces, but causes errors when I try to use an enum exported from this symlinked folder:
ERROR in ./functions/src/shared-types/roles.ts 3:0
Module parse failed: The keyword 'enum' is reserved (3:0)
File was processed with these loaders:
* ./node_modules/#pmmmwh/react-refresh-webpack-plugin/loader/index.js
* ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| __webpack_require__.$Refresh$.runtime = require('/Users/joel/my-project/node_modules/react-refresh/runtime.js');
|
> enum Roles {
| Admin = 'Admin',
| Access = 'Access',
Repro
Starting from a fresh create-react-app with typescript support, add a folder called shared-types at the same level as src and put a file in it called MyEnum.ts:
// shared-types/MyEnum.ts
enum MyEnum {
Foo = "foo",
Bar = "bar"
}
export default MyEnum;
Then, make a symlink between that folder and another one also called shared-types inside src:
$ ln -s /path/to/project/shared-types /path/to/project/src/shared-types
Then, import and use MyEnum in App.tsx:
// src/App.tsx
import React from 'react';
import './App.css';
import MyEnum from "./shared-types/MyEnum";
function App() {
return (
<div className="App">
<h1>{MyEnum.Bar}</h1>
</div>
);
}
export default App;
Finally, just run npm start:
ERROR in ./shared-types/MyEnum.ts 3:0
Module parse failed: The keyword 'enum' is reserved (3:0)
File was processed with these loaders:
* ./node_modules/#pmmmwh/react-refresh-webpack-plugin/loader/index.js
* ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| __webpack_require__.$Refresh$.runtime = require('/Users/joel/repro/node_modules/react-refresh/runtime.js');
|
> enum MyEnum {
| Foo = 'foo',
| Bar = 'bar',
Things that aren't causing it
It's not that typescript is ignoring the shared-types folder, as everything compiles fine if you add an interface to that folder and use it in App.tsx. Plus, running tsc --listFilesOnly will return a list including /path/to/project/src/shared-types/MyEnum.tsc.
It's not that my version of typescript doesn't support enums or that enums are disabled, as everything works fine if you add an enum to App.tsx itself.
Thanks in advance for the help! And feel free to suggest better ways of sharing files between these two projects in the comments if there are any!
It turns out that create-react-app doesn't support symlinks under src at all! The fact that the interface stuff worked at all seems to be a fluke.
https://github.com/facebook/create-react-app/issues/3547
This seems to have been a known issue for four years, but there is no blessed solution to it yet. 🫤
How can i use #import to import my components in my scripts from other folders in my react project.
For example i have a folder structure like this
src
|
--- App.jsx
|
--- pages
| |___ home.jsx
|
|
--- components
|__ HomeComponent.jsx
How can i use in home.jsx
import HomeComponent from "#components/HomeComponent"
if i just try to use import HomeComponent from "#components/HomeComponent" like
this i get error module not found.
You can do a relative import from pages/home.jsx like this
import HomeComponent from "../components/HomeComponent"
Here ../ means you are going up one directory level and then into components directory
You can also perform absolute imports by setting up additional tools like babel or webpack. An absolute import would look like this when you have set src as your root directory
import HomeComponent from "components/HomeComponent"
If you are using create-react-app, this setup is easy to do as all the tooling is already handled by create-react-app
You can read about it here under the absolute imports section - https://create-react-app.dev/docs/importing-a-component/
babel-plugin-module-resolver
This plugin can simplify the require/import paths in your project. For example, instead of using complex relative paths like ../../../../utils/my-utils, you can write #utils/my-utils. It will allow you to work faster since you won't need to calculate how many levels of directory you have to go up before accessing the file.
// Use this:
import MyUtilFn from 'utils/MyUtilFn';
// Instead of that:
import MyUtilFn from '../../../../utils/MyUtilFn';
// And it also work with require calls
// Use this:
const MyUtilFn = require('utils/MyUtilFn');
// Instead of that:
const MyUtilFn = require('../../../../utils/MyUtilFn');
Install the plugin
npm install --save-dev babel-plugin-module-resolver
or
yarn add --dev babel-plugin-module-resolver
Specify the plugin in your .babelrc with the custom root or alias. Here's an example:
{
"plugins": [
["module-resolver", {
"root": ["./src"],
"alias": {
"test": "./test",
"underscore": "lodash"
}
}]
]
}
.babelrc.js version
Specify the plugin in your .babelrc.js file with the custom root or alias. Here's an example:
const plugins = [
[
require.resolve('babel-plugin-module-resolver'),
{
root: ["./src/"],
alias: {
"test": "./test"
}
}
]
];
Good example: https://gist.github.com/nodkz/41e189ff22325a27fe6a5ca81df2cb91
My file.js has some functions that I would like to reuse in several vue projects, specifically within App.vue
the file structure is:
-- projec1
---- src
------ App.vue
-- project2
---- src
------ App.vue
-- myfile.js
I can't import it directly like that
import * as alias from '../../myfile.js'
because the file path is not found during the production build
ERROR Failed to compile with 1 error3: 21: 38 PM
This relative module was not found: ../../myfile.js
Is there a simple way to do this? Something in package.json like
{
myLocalDependency: path/to/myFile.js
}
and in App.vue to be able to do
<script>
import myLocalDependency from '...'
export default {
mounted: {
myLocalDependency.myPreciousFunction()
}
}
</script>
if your file.js is not very complicated you can use Adding Instance Properties to your Vue.js application. for example in your main.js file you should do something like this:
function converter(){}
Vue.prototype.$converter = converter();
And then you can use it anywhere in your vue project just like this.$converter
I am trying to develop a react component that could be shared across different applications. The idea is any app could drop in the component, pass in some props, and get the same functionality everywhere. So apps can add my component as a dependency in package.json which will be downloaded in node_modules. Basically go from doing this
import testComponent from "./Components";
to this
import testComponent from "my-custom-components";
I tried doing npm install [githun-url-link] which seemingly worked fine. But after launching the app I get the error:
Failed to Compile
./node_modules/.../src/components/testComponent.js
SyntaxError: /Users/mzq/Workspace/.../testing/node_modules/.../src/components/testComponent.js: Support for the experimental syntax 'classProperties' isn't currently enabled (7:9):
5 |
6 | class testComponent extends Component {
> 7 | state = {
| ^
8 | currentPageIndex: 0,
9 | currentPageLabel: this.props.currentPageLabel,
10 | page: this.props.pages[0],
Add #babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the 'plugins' section of your Babel config to enable transformation.
One solution I tried after a bit of Googling is
1) yarn add #babel/plugin-proposal-class-properties --dev
2) creating a babel.config.js in the root folder with following config
module.exports = {
presets: [
'#babel/preset-env',
'#babel/preset-react',
'#babel/preset-typescript'
],
plugins: [
'#babel/plugin-proposal-class-properties'
]
};
To no avail.
I get the file structure like this
before build
I want to make it like this below with webpack
after build
BTW, I also want to use ES6 import and export for the module loader,
such as in nav.js
class Nav extends Component {
// react code here
}
export defalt Nav
and in header.js
import Nav from `nav/bundle`
// header react code
// .......
export defalt Header
also need the bundle the redux and react-route npm package within the node_module
is it possible for webpack to do this stuff? some suggestions?
Here's a rough idea you could try to adapt:
{
// generate these dynamically through JavaScript
entry: {
footer: <path to footer js>,
...
},
output: {
path: './demo',
filename: '[name]/bundle.js' // name maps to entry keys
},
...
}