webpack adding testing module with mocha and chai - reactjs

So I have just started using mocha and chai (testing in browser), currently my webpack.config file for my app looks like this:
var webpack = require('webpack');
module.exports ={
entry: ["./js/app.js"],
output: {
path: "./js",
filename:"bundle.js"
},
module:{
loaders: [
{
test: [/\.es6$/, /\.js$/],
exclude: /(css|plugins|node_modules)/,
loader: 'babel-loader',
query: {
cacheDirectory: true,
presets: ['react', 'es2015']
}
},
{
test: [/\.scss$/],
loaders: ['style', 'css', 'sass']
}
]
},
plugins:[
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
],
resolve: {
extensions: ['', '.js', '.es6', '.jsx']
},
watch: false
}
Now my test folder is in the root directory, but let's say I want to use import/export, and import some react component for testing, what is the best practice?
do I have to create multiple entry point and output? One for my main app, one for the testing stuff, but how do I output the bundles in different directory. Or should I just create another webpack.config for the testing folder itself?

Each test you write will be in its own .js file. Your test runner will execute each of your test files independently.
Also your tests will not reference your bundle but, instead, import the required file(s) directly. You don't want to include the entire bundle during testing, as that adds a lot of code you do not need and can muddy your test development. Including only what is necessary means there is a much smaller footprint on what can interfere with your test results.
A useful link that covers getting setup for testing React components can be found:
https://www.toptal.com/react/how-react-components-make-ui-testing-easy
Also, Facebooks page for Reacts testing utilities:
https://facebook.github.io/react/docs/test-utils.html

Related

create-react-app webpack configuration file

I have created a new react app using npx create-react-app and now I want to integrate a webpack.config.js file. I know I don't have to but it is a necessary step for an assignment.
I have tried many tutorials an articles but I can't seem to make it work. All I need is to include all the css related loaders (sass, css etc) and babel.
This is my webpack.config.js file:
const path = require('path');
module.exports = {
mode: "development",
entry: path.join(__dirname,'./src/index.js'),
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader"
]
}
]
},
resolve: {
extensions: ["*", ".js", ".jsx"]
},
output: {
path: path.join(__dirname,'public'),
filename: 'bundle.js'
},
devServer: {
contentBase: path.join(__dirname,'public')
}
};
And I get this error:
ERROR in ./src/index.js 7:16
Module parse failed: Unexpected token (7:16)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| import * as serviceWorker from './serviceWorker';
|
> ReactDOM.render(<App />, document.getElementById('root'));
|
| // If you want your app to work offline and load faster, you can change
There're some alternatives that can override webpack config without ejecting the CRA project:
Alternatives You can try customize-cra for a set of CRA 2.0 compatible
rewirers, or any of the alternative projects and forks that aim to
support 2.0:
Rescripts, an alternative framework for extending CRA configurations
(supports 2.0+).
react-scripts-rewired for a fork of this project that
aims to support CRA 2.0
craco
add config-overrides.js in the route and add your webpack changes as:
const { addWebpackModuleRule } = require('customize-cra')
module.exports = {
webpack: override(
addWebpackModuleRule({
issuer: {
test: /\.sass?$/,
},
loader: 'file-loader',
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
}))
}
Answering this just because it kills me to see 10 page Medium articles as an answer when it can be answered in 1 sentence.
Enter your project dir and run npm run eject
This will extract all of the configuration files for you to edit, including webpack.config.js, to a folder called "config". Enter config/webpack.config.js, find the "return" statement, and inside there is a "resolve" configuration option. Add the following to that object:
symlinks: false
Boom. Saved you a stupidly long Medium article.

React Boilerplate's HMR very slow when editing dependency library (node module)

I'm using React Boilerplate which utilizes HMR (Hot Module Reload) in a dev environment.
However, I also have a custom component library which I load as a dependency. It has about 20 React components or so. The library is a UMD module which I load as a dependency through package.json in the boilerplate. It's also being built by Webpack and a build for it takes about 2 seconds.
When working locally on both projects though, I have the library linked in my boilerplate project (with 'npm link'), so I can see most recent changes.
Now, any time I make a change to anywhere in that dependency library, HMR kicks in for the boilerplate project, and that's great. But even the simplest change like a CSS color in that will take HMR around 20 seconds (!!!) to rebuild webpack in the boilerplate project.
That happens everytime the dependency is rebuilt, so 20 seconds when I make minor changes is very detrimental.
Can anyone please tell me how to mitigate that time? I feel like I am missing something. I'm running the default webpack config for boilerplate as it comes out of the box.
The dependency's webpack config is very similar to the boilerplate one, with a different output:
output: {
path: __dirname + '/dist',
filename: 'index.js',
library: 'my-component-library',
libraryTarget: 'umd',
umdNamedDefine: true,
},
The babel and style loaders are pretty much the same.
Thank you all for any suggestions that you may have.
To answer my own question, I did this:
https://github.com/uber/react-map-gl/issues/165#issuecomment-275412920
internals/webpack/webpack.base.babel.js
## ##
loaders: [{
test: /\.js$/, // Transform all .js files required somewhere with Babel
loader: 'babel-loader',
- exclude: /node_modules/,
+ include: [
+ path.resolve(process.cwd(), 'app'),
+ path.resolve(process.cwd(), 'node_modules/mapbox-gl/js'),
+ ],
query: options.babelQuery,
## ##
resolve: {
modules: ['app', 'node_modules'],
extensions: [
'.js',
'.jsx',
'.react.js',
],
mainFields: [
'browser',
'jsnext:main',
'main',
],
+ alias: {
+ 'mapbox-gl$': path.join(__dirname, '../../node_modules/mapbox-gl/dist/mapbox-gl.js'),
+ },
},
package.json
"env": {
"production": {
- "only": [
- "app"
- ],
"plugins": [
"transform-react-remove-prop-types",
"transform-react-constant-elements",
"transform-react-inline-elements"
]
},

Webpack: Can I get a source map for after babel, before minification?

I have a fairly basic webpack setup that runs babel and out comes my minified js with a source map.
Now when I run my source map in chrome I get the js before babel and before minification. However I would often like to have my source map after babel but before minification. Is this possible?
TL;DR I want source map to post-babel pre-minifcation. Possible?
For completeness
I run babel-loader 8 with webpack 4
Here is a screenshot from chrome showing the problem. As you can see the Dropzone tag indicates this is jsx (and so before babel)
Secondly here is my webpack config (not that it actually matters for my question).
const path = require('path');
module.exports = {
context: path.join(__dirname, 'Scripts', 'react'),
entry: {
client: './client'
},
output: {
path: path.join(__dirname, 'Scripts', 'app'),
filename: '[name].bundle.min.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: [require('#babel/plugin-proposal-object-rest-spread')],
presets: ["#babel/es2015", "#babel/react", "#babel/stage-0"]
}
}
}
]
},
resolve: {
extensions: ['.js', '.jsx']
},
externals: {
// Use external version of React (from CDN for client-side, or
// bundled with ReactJS.NET for server-side)
react: 'React'
},
devtool: 'source-map'
};
Running webpack with -d gives a second set of source maps in chrome that does the trick.

Can I set a "scope" for dependencies bundled by webpack?

I use webpack to to bundle a ReactJS component. This ReactJS component has some dependencies and one of them is jQuery. Right now I just run webpack to create the bundled script.
Now I'd like to integrate the bundled script (representing my ReactJS component) into a legacy application. This application uses another version of jQuery (by directly importing the jQuery javascript file).
I wonder if this can lead to any problems because of having two jQuery versions in one application.
I don't really understand how webpack handles the dependencies in the bundle. Are they kind of "scoped" in the bundle so that they don't affect parts of my legacy application? Or is there any way to do so?
My webpack.config:
var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: "./js/components/Application.js",
output: {
path: "./target/dist",
filename: "application.js"
},
module: {
loaders: [
{
loader: "babel-loader",
test: /\.js$/,
exclude: /(node_modules|dist|__tests__)/
},
{
loader: "style-loader!css-loader",
test: /\.css$/
},
{
test: /\.(jpg|png)$/,
loader: 'url-loader',
include: /img/
}
]
},
devtool: 'source-map',
plugins: [
new CopyWebpackPlugin([
{from: 'static/index.html'},
{from: 'css/*.css'},
{from: 'fonts/*'},
{from: 'img/*.*'},
{from: 'data/*'}
])
]
};

Why is my Webpack ReactJS App so large?

I have followed as many tips as I can find in packaging my Webpack ReactJS app for production. Unfortunately, the file size is still 3MB. What am I doing wrong?
Here is my Webpack Config file:
var path = require('path')
var webpack = require('webpack')
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: [
'webpack-hot-middleware/client',
'./index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle-webpack.js',
publicPath: './'
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true,
warnings: false
}
})
],
module: {
loaders: [
{
test: /\.js$/,
loaders: [ 'babel' ],
exclude: /node_modules/,
include: __dirname
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{test: /node_modules\/react-chatview/, loader: 'babel' }
]
}
}
Any help would be greatly appreciated!
I use the following command to package it:
> NODE_ENV=production webpack -p
I get the following output:
bundle-webpack.js 3.1 MB 0 [emitted] main
Best,
Aaron
Looks like you've still got a fair amount of dev stuff there, e.g. hot module replacement.
Take a look at webpack.config.prod.js at React Transform Boilerplate as a guide.
You may also be able to optimise your imports by including only the parts of the packages you need and leaving out the rest. See: Reduce Your bundle.js File Size By Doing This One Thing .
So, it turns out that David L. Walsh was correct that I had too much development stuff in my app. However, the answer provided did not resolve the issue.
I resolved the issue using 3 steps.
Remove all the "hot-reloading" plugins from my webpack configuration, as David instructed.
Remove the hot reloading "react-transform" plugin from my .babelrc file.
Change the "devtool" parameter to "source-map" from "cheap-module-eval-source-map"
After following those steps, the final bundle file was 340kb while the source map was still 3MB. Fortunately, I don't have to include the source map in my application, so it can be downloaded at 340kb, which is still fairly large, but reasonable for modern browsers running on modern internet connections.
I would up-vote David's answer, but I don't have enough reputation points yet to do so.

Resources