Webpack build issue with mobx and mobx-react - reactjs

I have a project that uses React and Mobx with Mobx-react.
My project runs perfectly fine locally. However, when built using webpack -p, I get a blank screen with the following error in the console:
webpack:///./~/mobx-react/index.js?:3 Uncaught Error: Cannot find module "mobx"
at webpackMissingModule (webpack:///./~/mobx-react/index.js?:3)
at webpackUniversalModuleDefinition (webpack:///./~/mobx-react/index.js?:3)
at eval (webpack:///./~/mobx-react/index.js?:10)
at Object.<anonymous> (bundle.js:18)
at n (bundle.js:1)
at eval (webpack:///./src/components/Category.jsx?:35)
at Object.<anonymous> (bundle.js:27)
at n (bundle.js:1)
at eval (webpack:///./src/components/CategoryNavsDates.jsx?:15)
at Object.<anonymous> (bundle.js:14)
Here is my webpack config:
var path = require('path');
var webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer')
var CopyWebpackPlugin = require('copy-webpack-plugin');
var BUILD_DIR = path.resolve(__dirname, 'build/');
var SOURCE_DIR = path.resolve(__dirname, 'src/');
module.exports = {
devtool: 'eval',
entry: SOURCE_DIR + '/index.jsx',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
cacheDirectory: true,
plugins: ['transform-decorators-legacy'],
presets: ['es2015', 'stage-0', 'react']
}
},
{
test: /\.css$/,
use: [
'style-loader',
{ loader: 'css-loader', options: { modules: true, importLoaders: 1, localIdentName: "[name]__[local]___[hash:base64:3] "} },
{ loader: 'postcss-loader', options: {} },
]
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
},
plugins: [
new webpack.LoaderOptionsPlugin({
options: {
postcss: function () {
return [
require('postcss-import'),
require('postcss-cssnext'),
];
},
}
}),
new CopyWebpackPlugin([{ from: 'index.html', to: '' },])
],
devServer: {
historyApiFallback: true
},
};
There is only one file using Mobx in my entire project, and that is the file the error refers to, Category.jsx.
Category.jsx sample:
import { observer } from 'mobx-react'
import { observable } from 'mobx'
...
#observer class Category extends React.Component {
#observable showingSmallMenu = false
...
}
As I say this all works perfectly fine locally.
What could be the problem here?

Does it make a difference if you import mobx before mobx-react?

In my case, that is caused by:
alias: {
mobx: __dirname + '/node_modules/mobx/lib/mobx.es6.js'
}
Remove mobx alias, then the problem is solved

Related

Webpack error "Module build failed: ERR_INVALID_ARG_TYPE"

I'm pretty new to react and am having some issues with web pack. All I'm trying to do is import a SVG file into my react project. I'm lost as to what is causing this as it doesn't give me much info about it. I would be grateful if anyone knows what's going on, thank you in advance lol.
Error code in console:
ERROR in ./src/img/flag/united-kingdom.svg
Module build failed: TypeError [ERR_INVALID_ARG_TYPE]: The "from" argument must be of type string. Received undefined
at validateString (internal/validators.js:120:11)
at Object.relative (path.js:437:5)
at Object.loader (C:\Users\Callum\Desktop\sites\csgo\mern\client\node_modules\file-loader\dist\index.js:78:72)
# ./src/components/header.js 12:0-74
# ./src/components/app.js
# ./src/app.js
My webpack file (webpack.common.js)
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
vender: [
'react', 'react-dom', 'redux',
'react-redux', 'react-router-dom',
'axios', 'prop-types']
},
output: {
path: path.resolve(__dirname, '../docs/'),
filename: "js/[name].[chunkhash].js"
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: path.resolve(__dirname, 'node_modules'),
loader: 'babel-loader'
},
{
test: /\.s?css$/,
exclude: path.resolve(__dirname, "node_modules"),
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
sourceMap: true
}
},'sass-loader'],
})
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'images/',
name: '[name][hash].[ext]',
},
},
],
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'file-loader?name=/fonts/[name].[ext]'
},
{
test: /\.(svg)$/,
exclude: /fonts/, /* dont want svg fonts from fonts folder to be included */
use: [
{
loader: 'svg-url-loader',
options: {
noquotes: true,
},
},
],
},
]
},
plugins: [
new HtmlWebpackPlugin({template: path.resolve(__dirname, 'src/index.html')}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
filename: "manifest.js",
chunks: ['vender']
}),
new ExtractTextPlugin({
filename: 'styles/style.css'
}),
]
}
Import code (literally all that references it):
import { ReactComponent as UKFlag } from '../img/flag/united-kingdom.svg'
Just had this problem, changed my file-loader in package.json from 6.2.0 to 6.1.1 and it fixed it

Webpack 4 configuration for react-toolbox

I try to upgrade my app from webpack 2 to webpack 4.16.5.
Because I want not again end up in a hard to understand some hundreds line config, I start with a minimal config. This is my current:
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const context = path.resolve(__dirname, "app");
module.exports = {
entry: {
home: "./index.js"
},
context,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.(css|sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader"
},
{
loader: "postcss-loader"
},
{
loader: "sass-loader"
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./index.html",
filename: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
resolve: {
extensions: [".js", ".jsx", ".css", "json"],
modules: [path.resolve(__dirname, "node_modules"), context]
}
};
But I run in problems importing the CSS files from react-toolbox i.e.:
import Dialog from 'react-toolbox/lib/dialog';
in a js file and also
#import "react-toolbox/lib/button/theme.css";
causes errors like this:
ERROR in ../node_modules/react-toolbox/lib/switch/theme.css (../node_modules/css-loader!../node_modules/postcss-loader/src!../node_modules/sass-loader/lib/loader.js!../node_modules/react-toolbox/lib/switch/theme.css)
Module build failed (from ../node_modules/css-loader/index.js):
Error: composition is only allowed when the selector is single: local class name not in ".disabled", ".disabled" is weird
Does anyone have a working application with wbpack4 and react-toolbox? Also, any hints on what may cause these errors are welcome!
I'm learning react.js with the js stack from scratch tutorial and try to using react-toolbox components.
Finnaly, i have a working demo with webpack 4 and the react-toolbox, it's based on the react-toolbox-example.
This is my settings:
add css-modules related packages
$ npm install postcss postcss-cssnext postcss-import postcss-loader css-loader style-loader
add a postcss.config.js
module.exports = {
plugins: {
'postcss-import': {
root: __dirname,
},
'postcss-cssnext': {}
},
};
add a webpack rule
...
{ test: /\.css$/, use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
importLoaders: 1,
localIdentName: '[name]--[local]--[hash:base64:8]'
}
},
'postcss-loader'
]},
...
add cmrh.conf.js - Using the css-modules-require-hook for SSR(Optional)
module.exports = {
generateScopedName: '[name]--[local]--[hash:base64:8]'
}
You can see all the settings in here, hope it will work for you.

Can not export webpack.config when modules:false

Inside my index.js I am using webpack-dev-middleware/webpack-hot-middleware where I require my webpack.config and use it for compiler.
index.js
const webpack = require('webpack')
const webpackConfig = require('../../webpack.config.js')
const compiler = webpack(webpackConfig)
const webpackDevMiddleware = require('webpack-dev-middleware')
app.use(webpackDevMiddleware(compiler, {
publicPath: webpackConfig.output.publicPath,
hot: true,
noInfo: true,
stats: {
colors: true
}
}))
app.use(require('webpack-hot-middleware')(compiler))
I try to export my webpack.config using Common.js by require and module.exports but I get error
TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
webpack.config
'use strict'
const path = require('path')
const webpack = require('webpack')
const publicPath = path.resolve(__dirname, './src/client')
const buildPath = path.resolve(__dirname, './src')
process.noDeprecation = true
module.exports = {
devtool: 'source-maps',
performance: {
hints: false
},
context: publicPath,
entry: {
bundle: [
'react-hot-loader/patch',
'webpack-hot-middleware/client?reload=false&noInfo=true',
'script-loader!jquery/dist/jquery.min.js',
'script-loader!tether/dist/js/tether.min.js',
'script-loader!bootstrap/dist/js/bootstrap.min.js',
'./app.js'
]
},
output: {
path: path.join(buildPath, 'dist'),
filename: '[name].js',
publicPath: '/'
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
CountdownForm: path.resolve(__dirname, 'src/client/scenes/countdown/components/CountdownForm.jsx'),
Countdown: path.resolve(__dirname, 'src/client/scenes/countdown/index.jsx'),
..
}
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules|dist|build/,
loader: 'babel-loader',
options: {
plugins: [
[
'babel-plugin-react-css-modules',
{
context: publicPath,
filetypes: {
'.scss': 'postcss-scss'
}
}
]
]
}
},
{
test: /\.local\.(css|scss)$/,
use: [
'style-loader',
'css-loader?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
'postcss-loader',
'sass-loader',
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, './src/client/styles/global/sass-resources.scss')
}
}
]
},
{
test: /^((?!\.local).)+\.(css|scss)$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
'sass-loader'
]
}
]
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
jquery: 'jquery'
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development')
}
})
]
}
If I use ES6 (I am using babel and this usually works) using import statements at the top instead of require and export default instead of module.exports I get this error
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration misses the property 'entry'.
All of this is because of modules:false inside my .babelrc If I remove that Common.js way works, but I need this. How can I export webpack.config to compiler using modules:false
{
"presets": [
"react",
["es2015", { "modules": false }],
"stage-0"
],
"plugins": [
"react-hot-loader/babel",
"transform-runtime"
]
}
transform-runtime adds import and that results in mixing import with your module.exports.
Simple fix would be to replace module.exports with es6 export
module.exports = { ...webpackconfig }
becomes
export default { ...webpackconfig }
and update your index.js to use default export
const webpackConfig = require('../../webpack.config.js').default
You can find more information about this on these issues
https://github.com/webpack/webpack/issues/4039
https://github.com/webpack/webpack/issues/3917

css modules object import returns empty

I am trying to use css modules inside react, but it is not working.
The log of this code:
import React from 'react'
import styles from '../../css/test.css'
class Test extends React.Component {
render() {
console.log(styles)
return (
<div className={styles.app}>
<p>This text will be blue</p>
</div>
);
}
}
export default Test
returns Object {}
and the rendered code are tags with no class:
<div><p>This text will be blue</p></div>
The css code is available at site, here is my test.css:
.test p {
color: blue;
}
If I changed the div to have class='test', the color of p changes to blue
Here is my webpack.config.js
var path = require('path')
var webpack = require('webpack')
var HappyPack = require('happypack')
var BundleTracker = require('webpack-bundle-tracker')
var path = require('path')
var ExtractTextPlugin = require("extract-text-webpack-plugin")
function _path(p) {
return path.join(__dirname, p);
}
module.exports = {
context: __dirname,
entry: [
'./assets/js/index'
],
output: {
path: path.resolve('./assets/bundles/'),
filename: '[name].js'
},
devtool: 'inline-eval-cheap-source-map',
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
new HappyPack({
id: 'jsx',
threads: 4,
loaders: ["babel-loader"]
}),
new ExtractTextPlugin("[name].css", { allChunks: true })
],
module: {
loaders: [
{
test: /\.css$/,
include: path.resolve(__dirname, './assets/css/'),
loader: ExtractTextPlugin.extract("style-loader", "css-loader!resolve-url-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]")
},
{
test: /\.scss$/,
include: path.resolve(__dirname, './assets/css/'),
loader: ExtractTextPlugin.extract("style-loader", "css-loader!resolve-url-loader!sass-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]")
},
{
test: /\.jsx?$/,
include: path.resolve(__dirname, './assets/js/'),
exclude: /node_modules/,
loaders: ["happypack/loader?id=jsx"]
},
{
test: /\.png$/,
loader: 'file-loader',
query: {
name: '/static/img/[name].[ext]'
}
}
]
},
resolve: {
modulesDirectories: ['node_modules'],
extensions: ['', '.js', '.jsx'],
alias: {
'inputmask' : _path('node_modules/jquery-mask-plugin/dist/jquery.mask')
},
}
}
Can anyone help me?
Thanks in advance.
Looks like your passing the css-loader params to the resolve-url-loader:
"css-loader!resolve-url-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]"
Should be:
"css-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]&importLoaders=1!resolve-url-loader"
A lot of time passed since this question, so my webpack was update many times with another technologies.
This webpack config is working:
...
module.exports = {
entry,
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
devtool:
process.env.NODE_ENV === 'production' ? 'source-map' : 'inline-source-map',
module: {
rules: [
{
test: /\.jsx?$/,
include: path.resolve(__dirname, './app/view/'),
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.pcss$/,
include: path.resolve(__dirname, './app/view/'),
use: [
{
loader: 'style-loader'
},
{
loader:
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
},
{
loader: 'postcss-loader',
options: {
plugins: function() {
return [
require('postcss-import'),
require('postcss-mixins'),
require('postcss-cssnext')({
browsers: ['last 2 versions']
}),
require('postcss-nested'),
require('postcss-brand-colors')
];
}
}
}
],
exclude: /node_modules/
},
{
test: /\.(png|svg|jpg|webp)$/,
use: {
loader: 'file-loader'
}
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
modules: [path.resolve(__dirname, 'node_modules')]
},
plugins
};
I guess that there is an issue with older versions at webpack with this line:
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
Try importLoaders and importLoader
You can see my repo too.
In my specific case, I'm using official utility facebook/create-react-app. You have to run the following command to get access to the webpack configuration:
npm run eject
You will then need to edit config/webpack.config.js and set the css-loader modules option to true.
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules:true <-----
}),

React, Webpack and Babel for Internet Explorer 9

Trying to support IE 9 for React. Upgraded to use babel 6.3.26 and babel-preset-es2015 and babel-preset-react for Webpack. However, when the file is loaded in IE 9, a syntax error occurs.
webpack.config.js
/* eslint-env node */
var path = require('path');
var packageJson = require('./package.json');
var _ = require('lodash');
var webpack = require('webpack');
var context = process.env.NODE_ENV || 'development';
var configFunctions = {
development: getDevConfig,
production: getProdConfig,
test: getTestConfig
};
var config = configFunctions[context]();
console.log('Building version %s in %s mode', packageJson.version, context);
module.exports = config;
function getLoaders() {
if (context.indexOf('test') === -1) {
return [
{
test: /\.js?$/,
exclude: /(test|node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015'],
plugins: ['transform-runtime']
}
}
]
} else {
return [
{
test: /\.js?$/,
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015'],
plugins: ['transform-runtime']
}
}
]
}
}
function getBaseConfig() {
return {
context: __dirname + "/src",
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
stats: {
colors: true,
reasons: true
},
resolve: {
extensions: ['', '.js', '.jsx']
},
module: {
loaders: _.union(
getLoaders(),
[
{
test: /\.scss$/,
loader: 'style!css!sass'
},
{
test: /\.eot$|\.svg$|\.woff$|\.ttf$/,
loader: 'url-loader?limit=30000&name=fonts/[name]-[hash:6].[ext]'
},
{
test: /\.(png|.jpe?g|gif)$/,
loader: 'url-loader?limit=5000&name=img/[name]-[hash:6].[ext]'
},
{
test: /\.mp4$/,
loader: 'url-loader?limit=5000&name=videos/[name]-[hash:6].[ext]'
}
]
)
}
};
}
function getDevConfig() {
return _.merge({}, getBaseConfig(), {
devtool: 'cheap-module-eval-source-map',
entry: [
'babel-polyfill',
'webpack-hot-middleware/client',
'./App'
],
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
eslint: {
emitError: false,
failOnError: false,
failOnWarning: false,
quiet: true
}
});
}
function getProdConfig() {
return _.merge({}, getBaseConfig(), {
devtool: 'source-map',
entry: [
'babel-polyfill',
'./App'
],
plugins: [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
compress: {
warnings: false
}
})
],
eslint: {
emitError: true,
failOnError: true
}
})
}
function getTestConfig() {
return _.merge({}, getBaseConfig(), {})
}
Checking bundle.js for the offending lines reveals the usage of const which is not ES5. Am I missing something here? Do I need to transpile ES6 code into ES5 for production usage?
IE9 is not compatible with ES6, so, yes, you must transform your ES6 code to ES5. I believe the problem is you aren't telling babel to use the react and es2015 presets. I'm sure you installed them on your machine, but the babel loader only does what you tell it.
Inside your getLoaders() function, add the presets to your babel loader configuration query:
query: {
plugins: ['transform-runtime'],
presets: ['react', 'es2015']
}
Hopefully, that works for you.
babel/babel-loader reference
I am using create-react-app (v16.4.2). I tried using the followings to get the default hello world working in IE9:
1:
import 'core-js/es6/map';
import 'core-js/es6/set';
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
2:
import "babel-polyfill";
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
But neither of them worked for me. I ended up adding the following line into my index.html file in the public folder and it fixed my issue:
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
More information is available at:https://polyfill.io/v2/docs/

Resources