React - Configure Store Getting Require not defined error - javascript

I have created configureStore.dev.js file to configure store for my react-redux app. Below is my code for configureStore.dev.js file.
I am getting "require not defined" error for the "const nextRootReducer = require('../reducers').default;".
How can I rewrite this part to solve the issue?
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import createLogger from 'redux-logger';
import StockApp from '../reducers';
import DevTools from '../containers/DevTools';
const createDevStoreWithMiddleware = compose(
applyMiddleware(thunk),
applyMiddleware(createLogger()),
DevTools.instrument()
)(createStore);
export default function configureStore() {
const store = createDevStoreWithMiddleware(StockApp);
// enable webpack hot module replacement for reducers
if (module.hot) {
module.hot.accept('../reducers', () => {
// eslint-disable-next-line
const nextRootReducer = require('../reducers').default;
store.replaceReducer(nextRootReducer);
});
}
return store;
}
Here is my webpack.config.js:
// We are using node's native package 'path'
// https://nodejs.org/api/path.html
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const nodeExternals = require('webpack-node-externals');
// Constant with our paths
const paths = {
DIST: path.resolve(__dirname, 'dist'),
SRC: path.resolve(__dirname, 'src'),
JS: path.resolve(__dirname, 'src/js'),
};
// Webpack configuration
module.exports = {
entry: path.join(paths.JS, 'app.js'),
output: {
path: paths.DIST,
filename: 'app.bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(paths.SRC, 'index.html'),
}),
new ExtractTextPlugin('style.bundle.css'),
],
// We are telling webpack to use "babel-loader" for .js and .jsx files
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
'babel-loader',
],
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
use: 'css-loader',
}),
},
{
test: /\.(png|jpg|gif)$/,
use: [
'file-loader',
],
},
],
},
// Enable importing JS files without specifying their's extenstion -> ADDED IN THIS STEP
//
// So we can write:
// import MyComponent from './my-component';
//
// Instead of:
// import MyComponent from './my-component.jsx';
resolve: {
extensions: ['.js', '.jsx'],
},
target: 'node',
externals: [nodeExternals()],
node: {
console: true,
fs: 'empty',
net: 'empty',
tls: 'empty'
},
// Dev server configuration -> ADDED IN THIS STEP
// Now it uses our "src" folder as a starting point
devServer: {
contentBase: paths.SRC,
},
};
Could anyone please help me solve this issue?
Thank you.

Hoping that you are using Babel 6+, you can replace this code:
const nextRootReducer = require('../reducers').default;
store.replaceReducer(nextRootReducer);
With this:
store.replaceReducer('.default')
No need to require. Hope it helps.

Related

How can I optimize webpack build by splitting entry point?

I want to optimize my webpack build file and tried to use code splitting (https://webpack.js.org/guides/code-splitting/). The largest part of my application is vuetify and I try to separate it from my index.js
Here is my index.js file:
import Vue from 'vue'
import App from './App.vue';
import router from './router/router'
import vuetify from './plugins/vuetify'
new Vue({
router,
vuetify,
el:'#vue-app',
render: a => a(App)
})
vuetify is configurated in ./src/plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
const opts = {}
export default new Vuetify(opts)
and here is my webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')
module.exports = {
// mode:'development',
entry: {
main: './src/index.js',
vuetify: './src/plugins/vuetify.js',
},
output: {
filename: '[name].bungle.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
new HtmlWebpackPlugin({
title: 'Development',
template:'./index.html'
}),
new VueLoaderPlugin(),
new VuetifyLoaderPlugin()
],
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
plugins: ['#babel/plugin-proposal-object-rest-spread']
}
}
},
{
//Правила для vue.js
test: /\.vue$/,
loader: 'vue-loader'
},
{
// Правила для обработки css стилей
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
},
{
test: /\.s(c|a)ss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sassOptions: {
fiber: require('fibers'),
indentedSyntax: true // optional
},
},
},
],
},
]
},
};
but when I run npm run build it makes two entry points:
Entrypoints:
main (452 KiB)
main.bungle.js
vuetify (315 KiB)
vuetify.bungle.js
With one entry point main.js is the same:
Entrypoints:
main (452 KiB)
main.bungle.js
Looks like in result application vuetify is build in main.bungle.js and not imported from vuetify.bungle.js. Another solution is to lazy-loading, but I still want to do this by code-splitting.

Require doesn't appear in my code, but webpack keeps throwing the error "require is not defined."

I'm writing an electron app with react. I run the developement version using this command:
webpack-dev-server --hot --host 0.0.0.0 --port 4000 --config=./webpack.dev.config.js
Here is the webpack.dev.config.js file
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { spawn } = require('child_process');
const helpers = require('./config/helpers');
// Config directories
const SRC_DIR = path.resolve(__dirname, 'src');
const OUTPUT_DIR = path.resolve(__dirname, 'dist');
// Any directories you will be adding code/files into, need to be added to this array so webpack will pick them up
const defaultInclude = [SRC_DIR];
module.exports = {
entry: SRC_DIR + '/index.js',
output: {
path: OUTPUT_DIR,
publicPath: '/',
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
include: defaultInclude
},
{
test: /\.jsx?$/,
use: [{ loader: 'babel-loader' }],
include: defaultInclude
},
{
test: /\.(jpe?g|png|gif)$/,
use: [{ loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]' }],
include: defaultInclude
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [{ loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]' }],
include: defaultInclude
}
]
},
target: 'electron-renderer',
plugins: [
new HtmlWebpackPlugin({
template: helpers.root('public/index.html'),
inject: 'body'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
})
],
devtool: 'cheap-source-map',
devServer: {
contentBase: OUTPUT_DIR,
stats: {
colors: true,
chunks: false,
children: false
},
setup() {
spawn(
'electron',
['.'],
{ shell: true, env: process.env, stdio: 'inherit' }
)
.on('close', code => {
console.error("electron exited with code ", code);
process.exit(0)
})
.on('error', spawnError => console.error(spawnError));
}
}
};
Once the electron browser opens it has the following error in the Dev-Tools console.
Uncaught ReferenceError: require is not defined
at Object.url (index.js:23)
at __webpack_require__ (bootstrap:709)
at fn (bootstrap:94)
at Object../node_modules/webpack-dev-server/client/utils/createSocketUrl.js (createSocketUrl.js:4)
at __webpack_require__ (bootstrap:709)
at fn (bootstrap:94)
at Object.<anonymous> (client:20)
at Object../node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:4000 (client:176)
at __webpack_require__ (bootstrap:709)
at fn (bootstrap:94)
The place where it claims this is occurring is at index.js:23.
Here is the build version of index.js:
import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { ipcRenderer as ipc } from "electron";
import { onUpdate } from "./actions/workerActions";
import { RECEIVED_STATE } from "./actions/types";
import "./assets/css/index.css";
import rootReducer from "./reducers/rootReducer";
import defaultState from "../config/defaultstate"; //Setup redux store
const middleware = [thunk];
const store = createStore(rootReducer, defaultState, applyMiddleware(...middleware));
ipc.on(RECEIVED_STATE, arg => {
console.log("Recieved State: ", arg);
onUpdate(arg)(store.dispatch);
}); // Now we can render our application into it
render(React.createElement(Provider, {
store: store
}, React.createElement(App, null)), document.getElementById("app"));
As you can see require does not appear here and all of the import aside from ipcRender are designed to run client-side, and therefore should not use required. I tried commenting out the ipcRender import but it resulted in the exact same error.
Most puzzlingly of all, I get the exact same error even with the entire index.js file commented out. The console still claiming the block comment contains a reference to require, which is not defined.
If you're using webpack directly then make sure you have the following in the webpack config that targets your renderer code.
// webpack.config.js
...
module.exports = {
...
target: 'web',
...
}
If you're using Vue then you'll need something like the following:
// vue.config.js
...
module.exports = {
...
configureWebpack: {
target: 'web'
},
...
}
Or, in my case I was using vue-cli-plugin-electron-builder and so need the following:
// vue.config.js
...
module.exports = {
...
pluginOptions: {
electronBuilder: {
nodeIntegration: false,
chainWebpackRendererProcess: config => {
config.target('web');
}
}
},
...
}
It turns out that the error is caused by importing electron's ipcRenderer which requires node integration and uses require. The reason that commenting out the import in the index.js didn't fix the error was because it was imported in other files.

Navigator undefined on React Typescript Firebase project

I've been googling for a couple hours now and can't seem to resolve my issue.
I have a webpack/React/Typescript/Mobx setup and am attempting to use firebase.
Here is my webpack config: (boilerplate from this repo)
var webpack = require('webpack');
var path = require('path');
// variables
var isProduction = process.argv.indexOf('-p') >= 0;
var sourcePath = path.join(__dirname, './src');
var outPath = path.join(__dirname, './dist');
// plugins
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var WebpackCleanupPlugin = require('webpack-cleanup-plugin');
module.exports = {
context: sourcePath,
entry: {
main: './main.tsx'
},
output: {
path: outPath,
filename: 'bundle.js',
chunkFilename: '[chunkhash].js',
publicPath: '/'
},
target: 'web',
resolve: {
extensions: ['.js', '.ts', '.tsx'],
// Fix webpack's default behavior to not load packages with jsnext:main module
// (jsnext:main directs not usually distributable es6 format, but es6 sources)
mainFields: ['module', 'browser', 'main'],
alias: {
app: path.resolve(__dirname, 'src/app/'),
assets: path.resolve(__dirname, 'src/assets/')
}
},
module: {
rules: [
// .ts, .tsx
{
test: /\.tsx?$/,
use: [
isProduction
? 'ts-loader'
: {
loader: 'babel-loader',
options: {
babelrc: false,
plugins: ['react-hot-loader/babel']
}
},
'ts-loader'
],
// : ['babel-loader?plugins=react-hot-loader/babel&presets=', 'ts-loader'],
exclude: /node_modules/
},
// css
{
test: /\.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
query: {
modules: true,
sourceMap: !isProduction,
importLoaders: 1,
localIdentName: '[local]__[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('postcss-import')({ addDependencyTo: webpack }),
require('postcss-url')(),
require('postcss-cssnext')(),
require('postcss-reporter')(),
require('postcss-browser-reporter')({
disabled: isProduction
})
]
}
}
]
})
},
{
test: /\.css$/,
include: /node_modules/,
use: ['style-loader', 'css-loader']
},
// static assets
{ test: /\.html$/, use: 'html-loader' },
{ test: /\.(png|jpg)$/, use: 'url-loader?limit=10000' },
{ test: /\.webm$/, use: 'file-loader' }
]
},
optimization: {
splitChunks: {
name: true,
cacheGroups: {
commons: {
chunks: 'initial',
minChunks: 2
},
vendors: {
test: /[\\/]node_modules[\\/]/,
chunks: 'all',
priority: -10
}
}
},
runtimeChunk: true
},
plugins: [
new WebpackCleanupPlugin(),
new ExtractTextPlugin({
filename: 'styles.css',
disable: !isProduction
}),
new HtmlWebpackPlugin({
template: 'assets/index.html'
})
],
devServer: {
contentBase: sourcePath,
hot: true,
inline: true,
historyApiFallback: {
disableDotRule: true
},
stats: 'minimal'
},
devtool: 'cheap-module-eval-source-map',
node: {
// workaround for webpack-dev-server issue
// https://github.com/webpack/webpack-dev-server/issues/60#issuecomment-103411179
fs: 'empty',
net: 'empty'
}
};
Just by including firebase in my app i relentlessly end up with this error:
Uncaught TypeError: Cannot read property 'navigator' of undefined auth.esm.js?69b5:10
I have tested by including a simple component like so:
import * as React from 'react';
import * as Styles from './styles.css';
import 'app/utils/FirebaseUtil';
interface TestProps {}
export const Test: React.StatelessComponent<TestProps > = () => (
<div className={Styles.root}>
{'Hello World'}
</div>
);
FirebaseUtil:
import * as firebase from 'firebase';
const config = {
apiKey: '**my key here**',
authDomain: '** my domain here **'
};
firebase.initializeApp(config);
export const fbAuth = firebase.auth;
No matter what I seem to do I get the navigator error. Even if i dont export the auth object. As far as I can tell its related to babel-loader adding strict-mode according to this SO question, i think? All other related searches seem to have to do with firebase-ui, which i am not using in any way.
But I have no idea how he manages to turn off strict mode, not to mention the OP is not using typescript and I am using ts-loader in this case. I can't for the life of me figure out how to get it working. Aside from all of this if I do try use the firebase object for auth() for example I get a bunch of warnings from webpack about auth not existing on the firebase object. Totally stumped.
So in case anyone else runs into this problem. It appears it was a package version issue. Im assuming that the package versions specifically included in the boilerplate i used didn't play well with firebase.
I updated typescript, react-hot-loader, and most likely the issue webpack from version 3.0.4 to 4.12.1 and things seem to be working ok now. Also with the updates I now import firebase like so:
import firebase from '#firebase/app';
import '#firebase/auth';
Hope this helps someone.
In my case I fixed this importing functions
import firebase from 'firebase/app'
import 'firebase/functions'
import 'firebase/analytics'

Webpack throws TypeError: Super expression must either be null or a function, not undefined when importing LESS file

I have the following in a file initialize.js:
import App from './components/App';
import './styles/application.less';
document.addEventListener('DOMContentLoaded', () => {
const app = new App();
app.start();
});
In webpack.config.js I have:
'use strict';
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const ProvidePlugin = webpack.ProvidePlugin;
const ModuleConcatenationPlugin = webpack.optimize.ModuleConcatenationPlugin;
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const extractLess = new ExtractTextPlugin({
filename: 'app.css',
});
const webpackCommon = {
entry: {
app: ['./app/initialize']
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader?presets[]=es2015'
}]
}, {
test: /\.hbs$/,
use: {
loader: 'handlebars-loader'
}
}, {
test: /\.less$/,
exclude: /node_modules/,
use: extractLess.extract({
use: [{
loader: 'css-loader'
}, {
loader: 'less-loader'
}],
// use style-loader in development
fallback: 'style-loader'
}),
}]
},
output: {
filename: 'app.js',
path: path.join(__dirname, './public'),
publicPath: '/'
},
plugins: [
extractLess,
new CopyWebpackPlugin([{
from: './app/assets/index.html',
to: './index.html'
}]),
new ProvidePlugin({
$: 'jquery',
_: 'underscore'
}),
new ModuleConcatenationPlugin(),
],
};
module.exports = merge(webpackCommon, {
devtool: '#inline-source-map',
devServer: {
contentBase: path.join(__dirname, 'public'),
compress: true,
port: 9000
}
});
I tried removing the the plugins and the contents of application.less, but I keep getting this error:
ERROR in ./node_modules/css-loader!./node_modules/less-loader/dist/cjs.js!./app/styles/application.less
Module build failed: TypeError: Super expression must either be null or a function, not undefined
at ...
# ./app/styles/application.less 4:14-127
# ./app/initialize.js
If I replace that LESS file with a CSS one and update the config it works fine, so I guess the problem has to do with less-loader.
I'm using Webpack 3.4.1, Style Loader 0.18.2, LESS Loader 4.0.5, Extract Text Webpack Plugin 3.0.0 and CSS Loader css-loader.
My bad, I didn't notice I was using an old less version. That was the culprit. Just updated it to 2.7.2 and the problem is gone.

How to use libraries from vendors.ts build with webpack importing once?

I am using this config:
'use strict';
const path = require('path');
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AssetsPlugin = require('assets-webpack-plugin');
const assetsPluginInstance = new AssetsPlugin();
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
cache: true,
watch: true,
devtool: 'cheap-module-source-map',
context: path.join(__dirname, "/src"),
entry: {
vendors: "./vendors",
main: "./main"
},
output: {
path: path.join(__dirname, '/public'),
publicPath: "/",
filename: "[name].js"
},
resolve: {
extensions: ['', '.ts', '.js']
},
module: {
loaders: [
{
test: /\.ts$/,
loader: 'awesome-typescript-loader',
exclude: [/\.(spec|e2e)\.ts$/]
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style', 'css')
},
{
test: /\.(scss|sass)$/,
loader: ExtractTextPlugin.extract('style', 'css?sourceMap!postcss-loader!resolve-url!sass?sourceMap')
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
loader: 'url?name=imgs/[name].[ext]&limit=100000'
},
{
test: /\.(svg|ttf|eot|woff|woff2)$/,
loader: 'file?name=fonts/[name].[ext]',
exclude: /\/src\/imgs\//
},
{
test: /\.json$/,
loader: 'json?name=data/[name].[ext]'
},
{
test: /index\.html$/,
loader: 'html'
},
{
test: /\.html$/,
loader: 'raw',
exclude: path.join(__dirname, "src/index.html")
}
]
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendors',
filename: 'vendors.js',
minChunks: 2
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
"window.jQuery": 'jquery'
}),
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
new ExtractTextPlugin("[name].css", {
disable: false,
allChunks: true
}),
new HtmlWebpackPlugin({
template: './index.html',
inject: 'body',
favicon: 'favicon.ico',
chunksSortMode: 'none'
}),
new AssetsPlugin({
filename: 'assets.json',
path: path.join(__dirname, 'public/')
}),
new CleanWebpackPlugin(['./public'])
],
postcss: function () {
return {
defaults: [autoprefixer({browsers: ['last 2 versions']})]
};
}
};
All work perfect. I get vendors.js with all libraries and main.js with only app code and logic. I want to save this state.
Look to vendors.ts:
// Polyfills
import 'angular2/bundles/angular2-polyfills.js';
// Angular 2
import 'angular2/platform/browser';
import 'angular2/core';
import 'angular2/http';
import 'angular2/router';
import 'rxjs/Observable';
import 'rxjs/Subject';
import 'jquery/dist/jquery.min.js';
import 'bootstrap/dist/js/bootstrap.min.js';
import 'lodash/lodash.min.js';
import 'moment';
import 'accounting/accounting.min.js';
//css
import './vendors.scss';
Here we have lodash library. If we open chrome console we can see it work.
Now I want to use lodash in my app.component.ts
export class AppComponent implements OnInit {
constructor() {
console.log(_.last([1, 2, 3]));
}
ngOnInit() {
}
}
I got this error: ERROR in [default] /home/g-montag/WebstormProjects/Chat/src/app/app.component.ts:17:16
Cannot find name '_'.
I need import library again, and if I do this, lodash library will imported in my main.js file. It works, but duplicate code.
So, finally the question :) How to import lodash or something else in vendors.ts and use it in app without importing again and again.
got this error: ERROR in [default] /home/g-montag/WebstormProjects/Chat/src/app/app.component.ts:17:16
Cannot find name '_'
Its a compile time error. Quick workaround: Create a vendor.d.ts file that contains:
declare var _:any;
More
See ambient declarations : https://basarat.gitbooks.io/typescript/content/docs/types/ambient/d.ts.html

Categories