React-Cesium webpack config loader issue - reactjs

I'm new to playing with Webpack configuration and attempting to incorporate React-Cesium into my project. I'm following along with the Github instructions for installing React-Cesium and running into this error:
Here is my webpack.config.js file after adding what the documentation told me to:
'use strict';
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
module: {
externals: {
cesium: "Cesium"
},
output: {
publicPath: "/"
// ...
},
alias: {
cesiumSource: "cesium",
cesium: "cesium/Cesium"
},
rules: [
{
test: /\.pug$/,
use: [
'pug-loader?self'
]
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
]
},
plugins: [
new UglifyJSPlugin()
new CopyPlugin([
{
from: `node_modules/cesium/Build/Cesium${prod ? "" : "Unminified"}`,
to: "cesium"
}
]),
new HtmlIncludeAssetsPlugin({
append: false,
assets: [
"cesium/Widgets/widgets.css",
"cesium/Cesium.js"
]
}),
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify(opts && prod ? "production" : "development"),
CESIUM_BASE_URL: JSON.stringify("/cesium")
}
})
}
],
};
The documentation is a little ambiguous and I'm not sure what's wrong. The documentation says to install npm i html-include-assets-plugin --save-dev. That command doesn't work, I get a 404 error when attempting to install it.
Is that what is causing the loader error? If not, then what is?

Related

React with Webpack, Typescript and Cypress Loader Error

I'm trying to configure cypress with a working configuration of webpack with React and Typescript. It seems to me that the babel-loader is not picking up the cypress/support/components.ts file because my webpack entry is ./src/index.tsx and the cypress folder is on the root not inside src.
Here is the error I'm getting...
========
Error: The following error originated from your test code, not from Cypress.
Module parse failed: Unexpected token (28:8)
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
| // Alternatively, can be defined in cypress/support/component.d.ts
| // with a at the top of your spec.
declare global {
| namespace Cypress {
| interface Chainable {
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
Cypress could not associate this error to any specific test.
We dynamically generated a new test to display this failure.
===========
Here is my cypress.config.ts
import { defineConfig } from 'cypress';
export default defineConfig({
component: {
devServer: {
framework: 'react',
bundler: 'webpack',
webpackConfig: require('./webpack.dev'),
},
includeShadowDom: true,
},
});
Here is my webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
module.exports = {
entry: {
main: './src/index.tsx',
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src', 'index.html'),
}),
],
module: {
rules: [
{
test: /\.(js|ts)x$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.(png|jpg)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[contenthash].[ext]',
outputPath: 'static/images',
},
},
},
{
test: /\.svg$/,
use: [
{
loader: '#svgr/webpack',
options: {
name: '[name].[contenthash].[ext]',
outputPath: 'static/images',
},
},
{
loader: 'file-loader',
options: {
name: '[name].[contenthash].[ext]',
outputPath: 'static/images',
},
},
],
},
{
test: /\.(woff|woff2)$/,
type: 'asset/resource',
generator: {
filename: 'static/fonts/[name][ext][query]',
},
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.jsx', '.js'],
plugins: [new TsconfigPathsPlugin()],
},
};
Here is my webpack.dev.js
const path = require('path');
const { merge } = require('webpack-merge');
const common = require('./webpack.common');
module.exports = merge(common, {
mode: 'development',
devServer: {
port: '9500',
static: {
directory: path.join(__dirname, 'src'),
},
open: false,
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader', // 2) injects styles into DOM
'css-loader', // 1) turns css into commonjs
],
},
],
},
devtool: 'eval-source-map',
});
Again this config is working and will build, the issue I'm have is bringing in Cypress using Typescript for our testing suite.
I've tried all sorts of different configs and using ts-loader with babel-loader, but I feel like I'm just missing how to get webpack to "pick up" the .ts files in the Cypress folder with is outside of my src.
Any suggestions are very much appreciated!

Webpack chunk loading using HTTP instead of HTTPS

I've just converted one of my React components to use lazy loading and although it builds OK, I'm getting a scrip-src CSP error because the chunk is attempting to load over HTTP instead of HTTPS which the site is running. (If I switch CSP off, I get a mixed-content error so it isn't the CSP itself that's causing the problem )
Content Security Policy: The page's settings blocked the loading of a resource at http://passport.local//app/assets/bundle/1.bundle.js ("script-src"). bootstrap:128
I'm using Webpack 4.46.0
Am I missing a setting to force it to use the same protocol as the main application?
Many Thanks.
Neil
My webpack config is below
const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = (env, argv ) =>
{
const IS_DEVELOPMENT = argv.mode === "development";
const IS_PRODUCTION = argv.mode === "production";
let plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// all options are optional
filename: path.join('..', 'css', 'app.css'),
//chunkFilename: '[id].css',
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
new webpack.DefinePlugin({
'__DEV__': JSON.stringify(true),
'__API_HOST__': JSON.stringify('https://passport.local/'),
}),
] ;
return {
devtool: 'source-map',
optimization: {
minimize: IS_PRODUCTION
},
entry: {
main: [
'./_devapp/app.js',
'./_devapp/css/app.scss'
],
login: [
'./_devapp/login.js',
]
},
output: {
path: path.resolve(__dirname, 'assets', 'bundle'),
filename: '[name].bundle.js'
},
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
alias: {
ui: path.resolve(__dirname, '_devapp/ui/'),
root: path.resolve(__dirname, '_devapp/')
}
},
module: {
rules: [
{
test: /\.(js|jsx|tsx|ts)$/,
exclude: path.resolve(__dirname, 'node_modules'),
use: {
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-env',
'#babel/preset-react',
'#babel/preset-typescript'
],
plugins: [
["#babel/plugin-proposal-decorators", {"legacy": true}],
'#babel/plugin-syntax-dynamic-import',
['#babel/plugin-proposal-class-properties', {"loose": true}],
["#babel/plugin-proposal-private-property-in-object", { "loose": true }],
["#babel/plugin-proposal-private-methods", {"loose": true}]
]
}
},
},
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: '../',
},
},
'css-loader',
'postcss-loader',
'sass-loader'
],
},
{
test: /.(png|woff(2)?|eot|ttf|svg|gif)(\?[a-z0-9=\.]+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '../css/[hash].[ext]'
}
}
]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
}
]
},
externals: {
myApp: 'myApp',
},
plugins: plugins,
};
}
I managed to resolve this. It was caused by a webpack_public_path definition buried in my code. I'd inherited this line in the react site template I used many years ago and never knew what it did... until now:
__webpack_public_path__ = `${window.STATIC_URL}/app/assets/bundle/`;
${window.STATIC_URL} is (at least on my platform) an http:// constant and overrides the https:// that the main site is running on.
Commenting out this line resolved the problem :-)

Autodesk React Forge problem with forge-dataviz-iot-react-components in a empty project

If you install the official npm package, it works.
But according to the official documentation and simply including import { Viewer } from "forge-dataviz-iot-react-components" (like in this example) in a empty new react project (using npx create-react-app) you will get this error:
./node_modules/forge-dataviz-iot-react-components/client/components/BasicTree.jsx 107:16
Module parse failed: Unexpected token (107: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
| if (node.children.length > 0) {
| return (
> <TreeItem
| id={`tree-node-${node.id}`}
| key={node.id}
Which loader do I need to add on webpack to avoid this error?
it is not possible to include the package https://www.npmjs.com/package/forge-dataviz-iot-react-components inside a react project made with npx create-react-app (hoping Autodesk is going to fix this problem soon).
You need to edit /node_modules/react-scripts/config/webpack.config.js in 2 parts:
one line about PIXI
...
alias: {
'PIXI': "pixi.js/",
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
// Allows for better profiling with ReactDevTools
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
}),
...(modules.webpackAliases || {}),
},
...
and another part about /forge-dataviz-iot-react-component
...
module: {
strictExportPresence: true,
rules: [
// Disable require.ensure as it's not a standard language feature.
{ parser: { requireEnsure: false } },
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
{
test: /forge-dataviz-iot-react-component.*.jsx?$/,
use: [
{
loader: require.resolve('babel-loader'),
options: {
presets: ["#babel/react", ["#babel/env", { "targets": "defaults" }]],
plugins: ["#babel/plugin-transform-spread"]
}
},
],
exclude: path.resolve(__dirname, "node_modules", "forge-dataviz-iot-react-components", "node_modules"),
},
// TODO: Merge this config once `image/avif` is in the mime-db
// https://github.com/jshttp/mime-db
{
test: [/\.avif$/],
loader: require.resolve('url-loader'),
options: {
limit: imageInlineSizeLimit,
mimetype: 'image/avif',
name: 'static/media/[name].[hash:8].[ext]',
},
},
...
after that on /node_modules/forge-dataviz-iot-react-components/client/components/Viewer.jsx you will get errors about undefined Autodesk variable easily fixable changing Autodesk with window.Autodesk.
Although you will not see any other errors, the package will not work.
I recently tried this package and I got the same problem.
So I created a React project from scratch without CRA and followed the webpack.config.js of this repo : Forge Dataviz IOT Reference App
Here's my webpack.config.js file :
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
},
resolve: {
modules: [path.join(__dirname, 'src'), 'node_modules'],
alias: {
react: path.join(__dirname, 'node_modules', 'react'),
PIXI: path.resolve(__dirname, "node_modules/pixi.js/"),
},
},
devServer: {
port: process.env.PORT || 3000
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{ loader: "babel-loader" }
]
},
{
test: /forge-dataviz-iot-react-component.*.jsx?$/,
use: [
{
loader: "babel-loader",
options: {
presets: ["#babel/react", ["#babel/env", { "targets": "defaults" }]],
plugins: ["#babel/plugin-transform-spread"]
}
},
],
exclude: path.resolve(__dirname, "node_modules", "forge-dataviz-iot-react-components", "node_modules"),
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
],
},
{
test: /\.svg$/i,
use: {
loader: "svg-url-loader",
options: {
// make loader to behave like url-loader, for all svg files
encoding: "base64",
},
},
},
],
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
}),
],
};
Update :
If you want to use CRA, you can customise your webpack config using Customize-CRA and create a config-overrides.js like this :
/* config-overrides.js */
const path = require("path");
const {
override,
addExternalBabelPlugins,
babelInclude,
babelExclude,
addWebpackAlias
} = require("customize-cra");
module.exports = override(
babelInclude([
path.resolve("src"), // make sure you link your own source
path.resolve("node_modules")
]),
babelExclude([path.resolve("node_modules/forge-dataviz-iot-react-components/node_modules")]),
addWebpackAlias({
['PIXI']: path.resolve(__dirname, 'node_modules/pixi.js/')
})
);
I managed to make this work on a fresh CreateReactApp project, so you should be able to make it working on your project.

Module parse failed: Unexpected character '#' (1:0) with Storybook 6.1.11, Webpack 5.11.0, React 17.0.1

Trying to setup a react-app with all latest versions.
Github Repo Link
Trying to run storybook with sass file imported will result in below error. Trying to run without importing the styles, storybook works.
The same code works correctly when its run as npm start run with no warnings and errors.
I have configured css modules using #dr.pogodin/babel-plugin-react-css-modules with sass, webpack 5, react 17 and with latest packages.
ERROR in ./src/assets/stylesheets/app.scss 1:0
Module parse failed: Unexpected character '#' (1:0)
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 "./base.scss";
| #import "./generics/font.scss";
| #import "./generics/spacing.scss";
# ./stories/index.js 5:0-44 8:2-10:4 8:58-10:3 9:4-49
# ./src/components/atoms/button/stories.js
babel.config.js
module.exports = {
presets: ["#babel/preset-env", "#babel/preset-react"],
plugins: [
[
"#dr.pogodin/babel-plugin-react-css-modules",
{
webpackHotModuleReloading: true,
autoResolveMultipleImports: true,
filetypes: {
".scss": {
syntax: "postcss-scss",
},
},
generateScopedName: "[name]__[local]___[hash:base64:5]",
},
],
],
};
webpack.config.js for css (partial code inlcuded)
{
test: /\.(css|sass|scss)$/,
exclude: /node_modules/,
use: [
isDev ? "style-loader" : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: {
auto: (resourcePath) =>
resourcePath.indexOf("assets/stylesheets") === -1,
localIdentName:"[name]__[local]___[hash:base64:5]",
},
sourceMap: true,
},
},
"sass-loader",
],
}
storybook/webpack.config.js file
const custom = require('../webpack.config.js');
module.exports = {
// stories: ['../src/components/**/*.stories.js'],
webpackFinal: (config) => {
return {
...config,
module: {
rules: custom.module.rules,
},
resolve: {
...config.resolve,
...custom.resolve,
}
};
},
};
I don't know what you have done with your configuration but you would define the config things inside .storybook/main.js. And for global style css is supposed to be included in preview.js file.
In short, you have to do the few things:
Remove your .storybook/config.js and add .storybook/main.js with following content:
const custom = require('../webpack.config.js');
module.exports = {
stories: [
'../src/**/stories.js', // The name should have a prefix for component name like `button.stories.js` instead of `stories.js` like you've done. As you renamed, you can remove this pattern
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
webpackFinal: (config) => {
return {
...config,
module: {
rules: custom.module.rules,
},
resolve: {
...config.resolve,
...custom.resolve,
}
};
},
};
Create the .storybook/preview.js to import your global style:
import "../src/assets/stylesheets/app.scss";
Some people have been running into problems a some scss preset when using Storybook 6.2.0 with Webpack 5. Instead of using a preset, I recommend configuring the Webpack config in main.js as mentioned above. Here's the relevant portion of a working Storybook Webpack config for Sass:
module: {
...config.module,
rules: [
...config.module.rules,
{
test: /\.(scss)$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: function () {
return [require('precss'), require('autoprefixer')];
},
},
},
},
{
loader: require.resolve('sass-loader'),
options: {
implementation: require('sass'),
},
},
],
},
],
},
I've written more about getting Storybook off the ground with Webpack 5 (and modifying the Storybook Webpack config) over here.
Another reason this might happen: if you are adding new components to your app and the path defined for your sass-loader does not match anymore.
E.g. if you have this in your .storybook/main.js:
webpackFinal: async config => {
// Add SASS support
// https://storybook.js.org/docs/configurations/custom-webpack-config/#examples
config.module.rules.push({
test: /\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: {
compileType: "icss",
},
},
},
"sass-loader",
],
include: path.resolve(__dirname, "../"),
})
Update or completely remove the include path.

Why do I see my entire react app in Chrome's Source tab

I can see my entire react app(with same directory and filenames) on Google chrome's Sources tab.
Why is it so?
I tried this both in dev and production:
In dev:
npm start
prod:
yarn global add serve
serve -s build
I can see the entire architecture and files, routing/ rendering logic.
Is there something I'm doing wrong, or maybe if could explain how a react server returns.
I would first check to make sure you are actually building a production build.
"build": "NODE_ENV=production webpack -p;",
I have seen no error with webpack but it infact didn't minify it.
Also, you will need to uglify() your production build to minify all code to computer only readable and in order to get the "blue production build" react logo if someone is using react dev tools in chrome, which is what I think you are looking to do.
https://webpack.js.org/plugins/uglifyjs-webpack-plugin/
Here is an example of a webpack config I use. There are obviously things here you don't need.
'use strict';
require('dotenv').config({ path: `${__dirname}/src/.dev.env` });
const production = process.env.NODE_ENV === 'production';
const { DefinePlugin, EnvironmentPlugin } = require('webpack');
const HtmlPlugin = require('html-webpack-plugin');
const CleanPlugin = require('clean-webpack-plugin');
const UglifyPlugin = require('uglifyjs-webpack-plugin');
const ExtractPlugin = require('extract-text-webpack-plugin');
let plugins = [
new EnvironmentPlugin(['NODE_ENV']),
new ExtractPlugin('bundle-[hash].css'),
new HtmlPlugin({ template: `${__dirname}/src/index.html` }),
new DefinePlugin({
__DEBUG__: JSON.stringify(!production),
__API_URL__: JSON.stringify(process.env.API_URL),
__GOOGLE_CLIENT_ID__: JSON.stringify(process.env.GOOGLE_CLIENT_ID),
__AWS_ACCESS_KEY_ID__: JSON.stringify(process.env.AWS_ACCESS_KEY_ID),
__AWS_SECRET_ACCESS_KEY__: JSON.stringify(process.env.AWS_SECRET_ACCESS_KEY),
}),
];
if(production) {
plugins = plugins.concat([new CleanPlugin(), new UglifyPlugin()]);
}
module.exports = {
plugins,
entry: `${__dirname}/src/main.js`,
devServer: {
historyApiFallback: true,
},
devtool: production ? undefined : 'eval',
output: {
path: `${__dirname}/build`,
filename: 'bundle-[hash].js',
publicPath: process.env.CDN_URL,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.scss$/,
loader: ExtractPlugin.extract(['css-loader', 'sass-loader']),
},
{
test: /\.(woff|woff2|ttf|eot|glyph|\.svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: 'font/[name].[ext]',
},
},
],
},
{
test: /\.(jpg|jpeg|gif|png|tiff|svg)$/,
exclude: /\.glyph.svg/,
use: [
{
loader: 'url-loader',
options: {
limit: 6000,
name: 'image/[name].[ext]',
},
},
],
},
{
test: /\.(mp3|aac|aiff|wav|flac|m4a|mp4|ogg)$/,
exclude: /\.glyph.svg/,
use: [
{
loader: 'file-loader',
options: { name: 'audio/[name].[ext]' },
},
],
},
],
},
};

Resources