I've searched and searched, but can't find an answer. Losing hope.
Here's the issue:
I have a component library that's built on React 17. I've bundled it using webpack 4.
The bundle gets generated and there don't seem to be any issues with it, until I tag it and attempt to use it in my work app.
Then I get the following error:
ReferenceError: react is not defined
The app compiles just fine, no errors. It only crashes when trying to use it.
Here's my webpack config for the library:
/* eslint-disable #typescript-eslint/no-var-requires */
const path = require('path');
const flexBugFixes = require('postcss-flexbugs-fixes');
const presetEnv = require('postcss-preset-env');
const autoprefixer = require('autoprefixer');
const normalize = require('postcss-normalize');
const nodeExternals = require('webpack-node-externals');
// const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
target: 'web',
mode: 'production',
entry: './src/index.tsx',
devtool: 'source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
library: 'RenezaComponents',
libraryTarget: 'umd'
},
module: {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-env',
[
'#babel/preset-react',
{
runtime: 'automatic'
}
]
]
}
},
'ts-loader'
],
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
flexBugFixes,
presetEnv({
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
}),
autoprefixer,
normalize()
]
}
}
}
],
sideEffects: true
},
{
test: /\.s(a|c)ss$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
flexBugFixes,
presetEnv({
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
}),
autoprefixer,
normalize()
]
}
}
},
'sass-loader'
]
},
{
test: /.(woff(2)?|ttf)/,
loader: 'file-loader'
},
{
test: /\.(png|svg|jpg|gif)$/,
loader: 'file-loader'
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
externals: nodeExternals()
};
The library gets installed using npm from our work private repository.
Example:
import { Button } from 'reneza-components'; // package.json has this as the library name
I've tried mucking about with externals, but none of them work. It always complains about the same thing.
The only other solution right now that I can come up with is just bundling react with it so it'd shut up. But that's not optimal.
I'm out of ideas. Perhaps anyone here would be a bit more clever than me?
Edit: Even bundling it together makes it throw the same error. So I'm all out of ideas.
Related
I currently have the current setup for my React app with SSR support:
React app
Express server that compiles the React app via webpack
Using babel-node to run the Express app with ES6 features etc
Everything is working fine, I fire up the Express app and it compiles my React app etc. However - then I started to CSS modules to the React app, and then of course it all broke down, on the server side only of course. It does not know how to handle my .scss files when they are being imported in the React app.
If we forget about the CSS part, everything is working as I want it to. I can run the whole application in "dev-mode", where I have hot reloading etc, babel-node is transpiling my ES6 node code etc.
And I have setup a build script which is compiling the node source to valid ES5, and the React app gets bundled into a single file. All good.
But how should I be able to keep my setup, but with the CSS modules working without Node is complaining it does not understand that code?
My half-way-solution I came up with was when I build everything for production I tell babel to skip my serverRender.js file (which is the one that imports my App.js, uses renderToString etc, and instead compile that specific file with Webpack (using isomorphic-style-loader, css-loader etc), and outputs it in the right folder for my "server" folder/structure. That works, but it just feels wrong.
And then if I come back to running in dev mode, I basically have the same issue again, if I dont setup Webpack for that part of the development too...
Any one that can tell me the better way to do this setup?
I had the same issue working on isomorphic React app. Whatever I tried, I either had a problem described in here: SCSS compilation in an isomorphic React app or the error below:
Error: Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
I was able to solve the problem by adding isomorphic-style-loader package to my server configs in the webpack.
Here is the client configs for the webpack:
var browserConfig = {
//usual stuff
module: {
rules: [{
//... ,
{
test: /\.scss$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
modules: true, //turns on the CSS Module mode
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]', //generates CSS class names
sourceMap: true
}
},
{
loader: 'sass-loader'
}
]
}
]
}
};
And server configs:
var serverConfig = {
//...
module: {
rules: [{
//... ,
{
test: /\.scss$/,
use: [
{
loader: 'isomorphic-style-loader',
},
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]',
sourceMap: true
}
},
{
loader: 'sass-loader'
}
]
}
]
},
}
With these configs in place, I was able to create styles.scss with simple styles:
$blueColor: #2196F3;
.component {
background: $blueColor;
}
Import it in the JS file:
import myStyles from './styles.scss';
And use it inside the React component in render():
<div className={ myStyles.component }>
This solution was kindly provided by DigitalKwarts, you can find more details about this solution here: https://blog.digitalkwarts.com/server-side-rendering-with-reactjs-react-router-v4-react-helmet-and-css-modules/
Let me know if it worked for you or of you were able to come up with a better solution.
I read #Galina answer and it's great. I set up a boilerplate using the article he has mentioned:
https://stackoverflow.com/a/68600509/6200607
Its config for webpack.config.js:
const path = require('path');
const isDevelopment = true;
module.exports = [
{
name: 'client',
target: 'web',
entry: './client.jsx',
output: {
path: path.join(__dirname, 'static'),
filename: 'client.js',
publicPath: '/static/',
},
resolve: {
extensions: ['.js', '.jsx']
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules\/)/,
use: [
{
loader: 'babel-loader',
}
]
},
{
test: /\.scss$/,
use: [
{
loader: 'style-loader',
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
sourceMap: isDevelopment,
}
},
{
loader: 'sass-loader'
}
]
}
],
},
},
{
name: 'server',
target: 'node',
entry: './server.jsx',
output: {
path: path.join(__dirname, 'static'),
filename: 'server.js',
libraryTarget: 'commonjs2',
publicPath: '/static/',
},
devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules\/)/,
use: [
{
loader: 'babel-loader',
}
]
},
{
test: /\.scss$/,
use: [
{
loader: 'isomorphic-style-loader',
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
sourceMap: isDevelopment,
}
},
{
loader: 'sass-loader'
}
]
}
],
},
}
];
I'm getting this error when viewing my app on IE11 and below. Also the app returns a white page.
To make things even worse, the console is not showing a line number to indicate what/where the problem is located. This makes it very hard to figure out what's wrong. I'm using Webpack 4 and babel-polyfill.
Can anyone point me in the right direction?
Webpack config
const HtmlWebPackPlugin = require("html-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const webpack = require('webpack');
const extractSass = new ExtractTextPlugin({
filename: "[name].[hash].css",
disable: process.env.NODE_ENV === "development"
});
module.exports = {
// mode: 'production',
entry: [
'babel-polyfill',
'./src/index.js'
],
output: {
publicPath: '/',
filename: '[name].[hash].js',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [{
loader: "file-loader",
options: {
// name: "./images/[name].[hash].[ext]",
name: '[path][name]-[hash:8].[ext]'
},
}
],
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.scss$/,
use: extractSass.extract({
use: [
{
loader: "css-loader",
options: {
minimize: true,
// sourceMap: true
}
},
{
loader: "sass-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
},
{
test: /\.css$/,
use: extractSass.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
devServer: {
historyApiFallback: true,
contentBase: './dist',
hot: true,
},
plugins: [
extractSass,
// new ExtractTextPlugin('[name].[hash].css'),
new CopyWebpackPlugin([
{from:'src/assets/img/favicon.png',to:'src/assets/img'}
]),
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
}),
new CleanWebpackPlugin(['dist']),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
],
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all'
}
}
}
},
};
I want to reiterate what Jornve realized, as it took me a while to figure this out as well. The query-string package will not work in IE. As it states in the docs,
This module targets Node.js 6 or later and the latest version of Chrome, Firefox, and Safari. If you want support for older browsers, or, if your project is using create-react-app, use version 5: npm install query-string#5.
Removing the dependency and writing my own implementations of the functions fixed the problem for me. I did not try using version 5 of the package, but perhaps that would fix it too.
I'm having a little bit of an issue when I want to implement auth0 on my project.
Whenever I solve one problem I run into another, it's always the same 3 errors :
-require is not a function
-window is not defined
-missing class properties
I've tried solving it by playing with the babelrc, changing the order of the presets
And in webpack I've added the famous as below:
"plugins: [new webpack.DefinePlugin({ 'global.GENTLY': false })],"
in webpack to no avail
I'm providing the package json/ babelrc & web pack without the modifications I cited above so you can see the "base" without the failed attempts at fixing it
Also providing the screenshots with the errors
Thanks in advance
https://imgur.com/a/8TT3v44
for the errors
this is in babelrc
{
"presets": [
"#babel/preset-react",
["#babel/preset-env", { "modules": false }],
["#babel/preset-stage-0", { "decoratorsLegacy": true }]
],
"env": {
"development": {
"compact": false
},
"jest": {
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
},
"plugins": [
"#babel/plugin-proposal-export-default-from",
[
"react-intl",
{
"messagesDir": "./extracted_messages/",
"enforceDescriptions": true
}
]
]
}
and this is the webpack
const path = require('path')
const CopyPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const webpack = require('webpack')
const distDir = path.join(__dirname, '../dist')
const srcDir = path.join(__dirname, '../src')
module.exports = [
{
name: 'client',
target: 'web',
mode: 'development',
entry: `${srcDir}/client.jsx`,
output: {
path: distDir,
filename: 'client.js',
publicPath: '/dist/'
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
config: path.join(__dirname, '../config'),
utils: path.join(__dirname, '../src/utils'),
toolbox: path.join(__dirname, '../src/components/toolbox')
}
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules\/)/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.(jpe?g|png|gif)$/,
loader: 'file-loader',
query: { name: 'assets/images/[name].[ext]' }
},
{
test: /\.(woff2?|eot|ttf|otf)$/,
loader: 'file-loader',
query: { name: 'assets/fonts/[name].[ext]' }
}
]
},
plugins: [
new webpack.DefinePlugin({ 'global.GENTLY': false }),
new MiniCssExtractPlugin({
filename: 'styles.css'
}),
new CopyPlugin([{ from: `${srcDir}/favicon.ico`, to: distDir }])]
},
{
name: 'server',
target: 'node',
mode: 'development',
entry: `${srcDir}/server.jsx`,
output: {
path: distDir,
filename: 'server.js',
libraryTarget: 'commonjs2',
publicPath: '/dist/'
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
config: path.join(__dirname, '../config'),
utils: path.join(__dirname, '../src/utils'),
toolbox: path.join(__dirname, '../src/components/toolbox'),
inherits: 'inherits/inherits_browser.js',
superagent: 'superagent/lib/client',
emitter: 'component-emitter',
}
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules\/)/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
{
loader: 'isomorphic-style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.(jpe?g|png|gif)$/,
loader: 'file-loader',
query: { name: 'assets/images/[name].[ext]' }
},
{
test: /\.(woff2?|eot|ttf|otf)$/,
loader: 'file-loader',
query: { name: 'assets/fonts/[name].[ext]' }
}
]
},
plugins: [
new webpack.DefinePlugin({ 'global.GENTLY': false }),
new CopyPlugin([{ from: `${srcDir}/favicon.ico`, to: distDir }])]
}
]
I ran into this problem while writing for our blog. Our suggested fix is this;
function whatYouRunOnPageLoad() {
if (typeof window !== undefined) {
auth0.parseHash(... etc ...)
}
}
parseHash requires window, which does not exist as part of your render steps. Auth0.js cannot run from serverside, which is what is "accidentally" happening when you try to render it the way you are.
Window error solved by doing:
if(global.window){...}
and later on by just not calling the function I was using at inappropriate times.
Require is not a function solved with:
[new webpack.DefinePlugin({ 'global.GENTLY': false })]
in the webpack config at plugins (dev AND prod, idk why) + importing it with require and not import.
Webpack module error solved by changing the order of the presets in bablerc.
I'm using webpack 3 for my angular app. I have some issues with compiling my scss files. Here is full webpack config file:
const path = require('path')
const autoprefixer = require('autoprefixer')
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const config = {
context: __dirname + '/src',
entry: {
app: './index.js',
vendor: [
'angular',
'angular-animate',
'angular-bootstrap',
'angular-route',
'animate',
'bootstrap',
'bootstrap-filestyle',
'jquery',
'ng-file-upload',
'ng-parallax'
]
},
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'app'),
publicPath: path.join(__dirname, 'app')
},
resolve: {
extensions: ['.js', '.jsx', '.scss']
},
module: {
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader',
'css?minimize!postcss!sass')
},
{
test: /\.(eot|woff|woff2|ttf|svg)(\?\S*)?$/,
loader: 'file?name=fonts/[name].[ext]'
},
{
test: /\.(jpg|jpeg|gif|png|svg)$/,
loader: 'file?name=images/[name].[ext]'
}
],
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
},
{
test: /\.svg$/,
loader: 'url-loader'
},
{
test: /\.php$/,
loader: 'file-loader?name=[name].[ext]'
},
{
test: /\.zip$/,
loader: 'file-loader?name=[name].[ext]'
},
{
test: /(\.png|\.jpg|\.gif)$/,
loader: 'file-loader?name=[path][name].[ext]'
}
]
},
plugins: [
new ExtractTextPlugin('./bundle.css'),
new CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.bundle.js'
}),
new UglifyJSPlugin({})
// new ExtractTextPlugin({
// filename: '[name].min.css'
// })
]
}
module.exports = config
After running webpack i've got this error:
ERROR in ./assets/sass/main.scss
Module parse failed: /home/git/project/src/public/src/assets/sass/main.scss Unexpected token (1:13)
You may need an appropriate loader to handle this file type.
| $header-color: #ffffff;
| $admin-panel-height: 40px;
|
# ./index.js 3:0-34
Also i tried to use this loader: https://github.com/webpack-contrib/sass-loader
After webpack build there no errors appeared, but css file also was not created in /app folder.
file main.scss imports in index.js:
import './assets/sass/main.scss'
Can anyone give me an advice how can i build and watch scss files with webpack 3 ?
You have used some of the loader configs that suppose to be for webpack 1.
That section of the config:
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader',
'css?minimize!postcss!sass')
},
{
test: /\.(eot|woff|woff2|ttf|svg)(\?\S*)?$/,
loader: 'file?name=fonts/[name].[ext]'
},
{
test: /\.(jpg|jpeg|gif|png|svg)$/,
loader: 'file?name=images/[name].[ext]'
}
],
There are breaking changes when you move to Webpack 2 (or 3).
One of them was module.loaders => module.rules.
You will need to convert that section to the new structure.
In addition, ExtractTextPlugin changes it config style as well, please read it README.
I have pretty common problem with vuejs i have error:
Failed to mount component: template or render function not defined,
but none of the other answers helped me. I know this is a problem with Standalone vs Runtime vuejs version explained here, but I am not sure how to solve it or where to look.
So i am trying to make jquery plugin component in vue i have only one .vue
nothing special in it.
Webpack configuration is this:
let webpack = require('webpack');
let path = require('path');
module.exports = {
entry: {
vuedatepickerrange: [
'./src/index.js'
]
},
output: {
path: path.resolve(__dirname, './../dist'),
publicPath: 'dist/',
filename: 'vuedatepickerrange.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.vue$/,
exclude: /node_modules/,
loader: 'vue-loader'
},
{
test: /\.(gif|jpe?g|png|svg)(\?.*)?$/,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {}
}
]
},
{
test: /\.s[a|c]ss$/,
loader: 'sass-loader',
},
],
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js',
jquery: "jquery/dist/jquery"
}
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
sourcemap: true,
compress: {
warnings: false
}
}),
new webpack.optimize.CommonsChunkPlugin({
names: ['vuedatepickerrange']
}),
new webpack.ProvidePlugin({
$ : "jquery",
jQuery : "jquery",
"window.jQuery" : "jquery",
"root.jQuery" : "jquery"
})
]
}
I am importing the correct vue library. I'm using webpack 2 so i am importing vue/dist/vue.esm.js instead of webpack 1 vue/dist/vue.common.js but other than that i think i got everything covered.
Only when i try to include it in other project this happens. When i try my demo example withing the project everything works.
You can see all the code and entire project here