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'));
});
Related
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'],
};
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/
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>
TL;DR: I'm getting build files that are way too big. I want them to be small and use the React source files from a CDN.
My Gulp file contains this:
gulp.task('build', () => {
browserify({
entries: dirs.src + '/index.jsx',
extensions: ['.jsx'],
debug: false
})
.transform(babelify.configure({
presets: ["es2015", "react"]
}))
.bundle()
.pipe(source('index.js'))
.pipe(gulp.dest(dirs.dest));
});
And said index.jsx file contains:
import { Provider } from 'react-redux';
import slides from './stores/slides';
const store = slides();
ReactDOM.render(
<Provider store={store}>
<h1>Test</h1>
</Provider>,
document.getElementById('target')
);
React Redux is pretty small. And if I remove that part from the latter file the result is a mere 1 KB in size. Otherwise it'll turn into 700Kb+.
I already removed these two lines from that file:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
Because I wanted to load React and ReactDOM from a CDN. Why are my files still this incredibly large?
You're currently using the development version of React. You have to build your own production version, for that the process.env.NODE_ENV flag has to be set to production.
If you're using browserify, you need envify: https://github.com/hughsk/envify
npm install envify --save-dev
Your Gulpfile.js
var envify = require('envify/custom');
//...
.transform(babelify.configure({
presets: ["es2015", "react"]
}))
.transform(envify({
NODE_ENV: 'production'
}))
//...
More resources: http://dev.topheman.com/make-your-react-production-minified-version-with-webpack/
I'm loading Ready through script tags from a CDN. I don't want to have the entire React codebase in my own local project files.
In this case, your production Webpack config should specify React in externals config option:
{
// ...
externals: {
"react": "React",
"react-dom": "ReactDOM"
},
// ...
}
Otherwise Webpack will bundle it.
Also verify that you don’t have a devtool option in the production config. It can bloat the code immensely if you use 'eval' or even inline sourcemaps.
I know uglify, but I don't want my code uglified
You should be using uglify for your code in production. This is the only way to have small builds.
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.