webpack Resolve conflict? Should I use alias? - reactjs

I'm trying to configure webpack to use clean import in my react app:
import { userConstants } from 'constants';
instead of:
import { userConstants } from '../../constants';
In webpack.config.js I defined:
resolve: {
modules: [
"node_modules",
helpers.root('client/app')
],
extensions: ['*', '.js', '.jsx']
},
This worked very well until I added a folder called constants. I wonder if some kind of conflict might appear with my node_modules since I get an error that disappears when I change the folder name to _constants:
WARNING in ./client/app/actions/user.actions.js 83:12-25 "export
'userConstants' was not found in 'constants'
My question: Should I define an alias in the webpack config for each of my folders? components, containers, constants, reducers, actions, services?

yes you have to use alias for each of your folder like this:
alias: {
constants: path.resolve(APP_DIR, 'constants'),
api: path.resolve(APP_DIR, 'api'),
components: path.resolve(APP_DIR, 'components'),
reducers: path.resolve(APP_DIR, 'reducers'),
}
This would be helpful in resolving and importing modules. And make sure you have correct APP_DIR

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'],
};

Creating a smarter Webpack autoloader for React components (nested in their directories)

I could really do with a webpack guru to help explain if this is possible.
Here's my directory listing:
components/
Editor/
Editor.jsx
style.module.scss
UIListing/
UIListing.jsx
style.module.scss
In addition to a webpack alias to resolve within the components directory:
resolve: {
alias: {
['~']: `${path}/components/`
},
extensions: ['.js', '.jsx']
So when I currently import Editor:
import Editor from '~/Editor/Editor
This is fine for me. But, is there any way (without moving the components out of their directory that I can resolve it this way instead?
import Editor from '~/Editor
Figured a solution:
containers/
Editor.jsx
components/
Editor/
Editor.jsx
style.module.scss
UIListing/
UIListing.jsx
style.module.scss
Editor.jsx:
import Editor from '../components/Editor/Editor'
export default Editor
webpack.config.js:
resolve: {
alias: {
['~']: `${path}/containers/`
},
extensions: ['.js', '.jsx']
Unfortunately it does require some extra work, but in my case this proves useful as I have a boilerplate UI kit which needs to be easy to get coding from the get go.
import Editor from '~/Editor'

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/

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'));
});

How to config minified React+ReactDOM with Webpack

After too many unsuccessful trials my question is: What is the proper way to setup Webpack so that:
Use react.min.js + react-dom.min.js - not the npm installed sources
Don't parse/com them again, just bundle with my own components.
"React" and "ReactDOM" variables can be used from all .jsx files.
The tutorials and guides I found didn't work - or maybe I did some errors. Usually I got error in browser developer tools about missing variable React.
My aim is just to save parsing/bundling time. Now I parse React from scratch every time I bundle my app. And it takes tens of seconds on a slowish computer. In watch mode it is faster, but I find I'm doing unnecessary work.
Any ideas with recent React versions?
Assuming you have a webpack.config.js that looks something like this:
module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
...
]
}
};
You just need to specify React and ReactDOM as external dependencies (from the docs):
module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
...
]
},
externals: {
// "node/npm module name": "name of exported library variable"
"react": "React",
"react-dom": "ReactDOM"
}
};
The key point about the externals section is that the key is the name of the module you want to reference, and the value is the name of the variable that the library exposes when used in a <script> tag.
In this example, using the following two script tags:
<script src="https://fb.me/react-0.14.6.js"></script>
<script src="https://fb.me/react-dom-0.14.6.js"></script>
results in two top-level variables being created: React and ReactDOM.
With the above externals configuration, anytime in your source code you have a require('react'), it will return the value of the global variable React instead of bundling react with your output.
However, in order to do this the page that includes your bundle must include the referenced libraries (in this case react and react-dom) before including your bundle.
Hope that helps!
*edit*
Okay I see what you're trying to do. The webpack configuration option you want is module.noParse.
This disables parsing by webpack. Therefore you cannot use dependencies. This may be useful for prepackaged libraries.
For example:
{
module: {
noParse: [
/XModule[\\\/]file\.js$/,
path.join(__dirname, "web_modules", "XModule2")
]
}
}
So you'd have your react.min.js, react-dom.min.js, and jquery.min.js files in some folder (say ./prebuilt), and then you'd require them like any other local module:
var react = require('./prebuilt/react.min');
And the entry in webpack.config.js would look something like this (untested):
{
module: {
noParse: [
/prebuilt[\\\/].*\.js$/
]
}
}
The [\\\/] mess is for matching paths on both Windows and OSX/Linux.

Resources