Absolute module imports #app with jest and CRA - reactjs

I have my create-react-app bootstrap workspace setup to support module imports using #app/ as my root module.
I achieve this by adding this to my webpack config
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
'#app': path.resolve(__dirname, '../src')
},
However this does not seem to work with my jest tests. Anytime something is imported with #app the import is not resolved.
Anyone have a good solution to this

Related

How can I use absolute paths in my React styleguidist component library?

I have a React component library that is used in a React app. The component library is setup using Styleguidist and webpack. I've setup webpack to use absolute paths using:
webpackConfig: {
resolve: {
modules: [path.resolve(__dirname, 'src/'), 'node_modules'],
}
}
This works within the context of the component library. When I build the component library, the package looks like this:
/core
/components
/Table
/Row
When I import the components into my app, I get an error:
Module not found: Can't resolve components/Row in /Users/myusername/Sites/mysite/node_modules/#mypackage/core/components/Table
I understand why the paths don't match in the context of node_modules, but I would've expected Webpack to transform those import paths during the build process. Is there something I'm missing? Or is this not possible?
While Styleguidist uses webpack, it turns out the build script we were using does not, so the webpack config is irrelevant. Instead, our build script (https://www.npmjs.com/package/cod-scripts) uses babel.
We ended up having to add a separate babel.config.js file to define absolute paths for babel using the babel-plugin-module-resolver package.
npm install babel-plugin-module-resolver --saveDev
npm install #babel/preset-react --saveDev
babel.config.js
module.exports = {
plugins: [
[
'module-resolver',
{
root: ['./src'],
},
],
],
presets: ['#babel/preset-react'],
};

Typescript Module published in NPM Registry - Cannot find module when used in different project

I created a module using CRA (Create-React-App) - typescript and published the same to npm.
My goal is to add the module as a component in another CRA created typescript project. When I try to import the module it fails with below error.
Cannot find module: 'fbdemots'. Make sure this package is installed.
I do see the modules in the path "node_modules\fbdemots".
I tried the below which did not help
Creating declaration files(d.ts) both in the module and the project which uses the module
Updating the TSConfig as mentioned in below link
Below links does not help, as I cannot change the
"module": "esnext", --> to "CommonJS" since CRA (Create-React-App) does not allow me to.
"moduleResolution": "node", "esModuleInterop" : "true"
`Cannot find module` for my own TypeScript module
Wait! Why I see the fbdemots of node_modules is a project, not component, and it can't be exported at all
If you want to publish a component, you can follow these common steps, of course there are other methods you can try.
If you don't want to use rollup/webpack or feel a bit complicated, you can just export your plain component, and then publish it.
1. Create a component and export it
// index.tsx
import React from 'react'
const Test = (props: {a: string})=> <div>{props.a}</div>
export default Test
2. Using rollup or Webpack to build it to make sure it would be usable for JS modules
Install some necessary modules
yarn add --dev rollup rollup-plugin-typescript2
Then create rollup.config.js file at root, if there are other files like '.css', '.scss', then you should install and add some plugins like rollup-plugin-sass or rollup-plugin-css-only...
// rollup.config.js
import typescript from 'rollup-plugin-typescript2';
// import sass from 'rollup-plugin-sass';
export default {
input: 'index.tsx', // the path of your source file
output: [
{
dir: 'lib',
format: 'cjs',
exports: 'named',
sourcemap: false,
strict: false,
},
],
plugins: [typescript()],
// plugins: [sass({ insert: true }), typescript()],
external: ['react', 'react-dom'],
};
3. Create lib
Using the command of rollup to build it
npx rollup -c
And then prepare package.json, LICENSE, README.md... into lib dir,
finally you can publish it
npm publish ./lib --access public
The end of the last, you can add it as a component in another CRA created typescript project!

Absolute Imports in React app WITHOUT create-react-app

There are lots of resources out there explaining how to do absolute imports in React with create-react-app
But I want to add absolute imports to an existing project which wasn't created through create-react-app. Is anyone aware of a guide for how to do this?
Not sure if this is the best way to do it...
But adding aliases in my resolver in webpack.config
resolve: {
extensions: ['.js', '.jsx'],
alias: {
src: path.resolve(__dirname, 'app')
}
}
Lets me replace imports like this
import Component from './../../src/Component';
With this
import Component from 'src/Component';
See https://webpack.js.org/configuration/resolve/

using webpack ProvidePlugin in React storybook custom webpack config

I've built a wrapper package for drag and drop in React, and I added storybook examples.
Since in my consumer React is exposed globally, i'm not importing React explicitly.
In the storybook examples I need to supply React as part of the custom webpack config, but for some reason it can't resolve React and I get a ReferenceError: React is not defined
This is the package - https://github.com/fiverr/drag_n_drop_package
And this is the custom webpack config file:
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.ProvidePlugin({
React: 'react'
})
],
module: {
loaders: [
{
test: /\.scss$/,
loader: 'style!raw!sass'
}
]
}
};
This is really strange but your storybook webpack.config.js is mixing webpack v1/v2.
Importing webpack as
const webpack = require('#kadira/storybook/node_modules/webpack');
solves it because it uses the same webpack reference that storybook is using (v1).
I found the following code in webpack.config.js at github:
externals: {
react: 'React'
}
It looks as this question. If it needs to load the React lib from external, like CDN. The page has to be sure have a script tag for importing React lib. And make sure this script tag is in front of the bundle.js or the file which it generated by webpack, so the Object of React will exist when the following code needs to use React, such as:
<script src="./react.js"></script>
<script src="./bundle.js"></script>

How to import from different bundle created with webpack

I have two project using webpack. Now I want to bring one project as module of other project. I can get the two bundle created but don't know how to import from the other bundle.
Elaborating a bit:-
Lets say the other file from which i want to import looks like as follows:-
index2.js (Bundled as bundleTwo)
import SomeCompoent from "./components/SomeCompoent/SomeCompoent";
module.exports = {SomeCompoent}
and in the file (is in another bundle - bundleOne) below I want to import the component (somecomponent):-
index1.js (in bundleOne)
import {SomeCompoent} from "bundleTwo";
but here bundleTwo is undefiend
Any help is highly appreciated
One way that I have figured out myself, is that using alias this can be achieved.
To make this line import {SomeCompoent} from "bundleTwo"; work, bundleTwo can be defined in alias :-
config:{
resolve: {
alias: {
"bundleTwo": path.join(__dirname, "<path_to_the_bundleTwo>")
}
....
If you want to use webpack only,then just set the libraryTarget to 'umd' in bundletwo webpack configuration.
In order to be able to import this module, you need to export your bundle.
output: {
libraryTarget: 'umd',// make the bundle export
filename: "index.js",
path: path.resolve(__dirname, "dist"),
}
However, this can also be achieved by just using Babel to transpile your ES6 code to ES5 code.
babel index2.js --out-file dist/index2.js
Now set the main in package.json to "dist/index2.js"
Now you can use it like
import {SomeCompoent} from "bundleTwo";
You can also create a gulp script for that
gulp.task('js', function () {
return gulp.src(['packages/**/*.js', "!**/*.test.js"])
.pipe(babel({
plugins: ['transform-runtime']
}))
.pipe(gulp.dest('dist'));
});

Resources