Related
Background
Need to create an external React component library using existing components from a Next.js site, using Tailwindcss#^2. This needs to be pulled in using npm, onto any site that requires the components.
Problem
I've managed to create the package using Webpack#^5 to compile. This is all fine, but the problem I face is that, the components don't work when reintroduced to the initial site. I have a feeling this is either the compiling is wrong or the fact that Next.js is server side rendered, or it could be both.
Attempted solution
I have tried to use Rollup as an alternate solution to compile the components, but I keep running into an issue with Postcss. A common issue I've noticed, where it's asking for v8 of PostCss (which it appears is present in node_modules), but it still complains. I did have a similar issue when using Webpack, but was eventually able to fix this. I've tried similar methods to fix for Rollup, but no luck.
package.json
{
"name": "#github_account/package_name",
"description": "Lorem ipsum",
"author": "github_account",
"version": "1.0.0",
"license": "ISC",
"repository": {
"type": "git",
"url": "repo_name_here"
},
"main": "./build/main.cjs.js",
"module": "./build/main.esm.js",
"browser": "./build/main.js",
"source": "./src/index.js",
"publishConfig": {
"registry": "https://npm.pkg.github.com/github_account"
},
"scripts": {
"build-rollup": "rollup -c",
"build": "webpack --mode production"
},
"dependencies": {
"#babel/runtime": "^7.17.8",
"autoprefixer": "^9.8.8",
"classnames": "^2.2.6",
"formik": "^2.2.6",
"iframe-resizer-react": "^1.1.0",
"luxon": "^2.0.2",
"prop-types": "^15.8.1",
"react": "^17.0.0",
"react-collapsible": "^2.8.4",
"react-device-detect": "^2.1.2",
"react-dom": "^17.0.0",
"react-google-recaptcha-v3": "^1.9.7",
"react-icons": "^3.10.0",
"react-markdown": "^6.0.3",
"react-modal": "^3.14.4",
"react-select": "^5.0.0",
"react-slick": "^0.28.1",
"react-table": "^7.7.0",
"sass": "^1.42.1",
"slick-carousel": "^1.8.1",
"yup": "^0.32.8"
},
"devDependencies": {
"#babel/core": "^7.18.6",
"#babel/plugin-syntax-jsx": "^7.18.6",
"#babel/plugin-transform-runtime": "^7.18.9",
"#babel/preset-env": "^7.18.6",
"#babel/preset-react": "^7.18.6",
"#rollup/plugin-babel": "^5.3.1",
"#rollup/plugin-commonjs": "^22.0.1",
"#rollup/plugin-node-resolve": "^13.3.0",
"#squoosh/lib": "^0.4.0",
"autoprefixer": "~9",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.2.5",
"clean-webpack-plugin": "^4.0.0",
"cross-env": "^7.0.2",
"css-loader": "^6.7.1",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.7.0",
"eslint-config-standard": "^14.1.0",
"eslint-config-standard-react": "^9.2.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-standard": "^4.0.1",
"image-minimizer-webpack-plugin": "^3.2.3",
"microbundle-crl": "^0.13.11",
"mini-css-extract-plugin": "^2.6.1",
"next": "^12.1.0",
"next-seo": "^4.28.1",
"npm-run-all": "^4.1.5",
"path": "^0.12.7",
"postcss": "8.4.6",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-import": "^14.1.0",
"postcss-loader": "^4.3.0",
"postcss-nested": "^5.0.6",
"postcss-preset-env": "^6.7.1",
"prettier": "^2.3.1",
"react-scripts": "^3.4.1",
"rollup": "^2.77.0",
"rollup-plugin-filesize": "^9.1.2",
"rollup-plugin-image": "^1.0.2",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-tailwindcss": "^1.0.0",
"sass-loader": "^12",
"tailwindcss": "^2.2.6",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-node-externals": "^3.0.0"
}
}
webpack.config.js
const path = require("path");
const webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const nodeExternals = require("webpack-node-externals");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const stylesHandler = MiniCssExtractPlugin.loader;
module.exports = {
devtool: "source-map",
context: __dirname,
entry: "./src/index.js",
externals: [nodeExternals({ importType: "umd" })],
output: {
filename: "[name].js",
path: path.resolve(__dirname, "./dist"),
libraryTarget: "umd",
library: {
name: "cruil",
type: "umd",
},
assetModuleFilename: (pathData) => {
const filepath = path.dirname(pathData.filename).split("/").slice(1).join("/");
return `${filepath}/[name].[hash][ext][query]`;
},
globalObject: "this",
},
experiments: {
outputModule: true,
},
optimization: {
runtimeChunk: "single",
minimizer: [
"...",
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.squooshMinify,
options: {
encodeOptions: {
pngquant: {
quality: 90,
},
},
},
},
}),
],
splitChunks: {
chunks: "all",
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// npm package names are URL-safe, but some servers don't like # symbols
return `npm.${packageName.replace("#", "")}`;
},
},
},
},
},
module: {
rules: [
{
test: /\.js$|jsx/,
include: path.resolve(__dirname, "./src"),
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"],
},
},
},
{
test: /\.(s(a|c)ss)$/,
use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"],
include: path.resolve(__dirname, "./src"),
},
{
test: /\.css$/i,
use: [stylesHandler, "css-loader", "postcss-loader"],
},
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
include: path.resolve(__dirname, "./src/assets"),
type: "asset/resource",
},
],
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin(),
new webpack.DefinePlugin({
"process.env": {
// This has effect on the react lib size
NODE_ENV: JSON.stringify("production"),
},
}),
],
};
rollup.config.js
import babel from "#rollup/plugin-babel";
import resolve from "#rollup/plugin-node-resolve";
import commonjs from "#rollup/plugin-commonjs";
import postcss from "rollup-plugin-postcss";
import filesize from "rollup-plugin-filesize";
import autoprefixer from "autoprefixer";
import image from "rollup-plugin-image";
import external from "rollup-plugin-peer-deps-external";
import replace from "rollup-plugin-replace";
import tailwind from "rollup-plugin-tailwindcss";
import pkg from "./package.json";
const INPUT_FILE_PATH = "src/index.js";
const OUTPUT_NAME = "main";
const GLOBALS = {
react: "React",
"react-dom": "ReactDOM",
"prop-types": "PropTypes",
};
const getBabelOptions = ({ useESModules }) => ({
babelrc: false,
exclude: "node_modules/**",
extensions: [".js", ".ts", ".jsx", ".tsx"],
babelHelpers: "runtime",
presets: [["#babel/preset-env", { modules: false }], "#babel/preset-react"],
plugins: [["#babel/transform-runtime", { regenerator: false, useESModules }], "#babel/plugin-syntax-jsx"],
});
const PLUGINS = [
external({
includeDependencies: true,
}),
image(),
tailwind({
input: "./src/styles/index.css",
purge: false,
}),
postcss({
extract: true,
modules: true,
plugins: [autoprefixer],
}),
resolve({
browser: true,
resolveOnly: [/^(?!react$)/, /^(?!react-dom$)/, /^(?!prop-types)/],
preferBuiltins: false,
}),
commonjs({
include: /node_modules/,
}),
replace({ "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) }),
babel(getBabelOptions({ useESModules: true })),
filesize(),
];
const EXTERNAL = ["react", "react-dom", "prop-types"];
// https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers
const CJS_AND_ES_EXTERNALS = EXTERNAL.concat(/#babel\/runtime/);
const OUTPUT_DATA = [
{
file: pkg.browser,
format: "umd",
},
{
file: pkg.main,
format: "cjs",
},
{
file: pkg.module,
format: "es",
},
];
const config = OUTPUT_DATA.map(({ file, format }) => ({
input: INPUT_FILE_PATH,
output: {
file,
format,
name: OUTPUT_NAME,
globals: GLOBALS,
},
external: ["cjs", "es"].includes(format) ? CJS_AND_ES_EXTERNALS : EXTERNAL,
plugins: PLUGINS,
}));
export default config;
postcss.config.js
module.exports = {
plugins: [
require("postcss-import"),
require("tailwindcss"),
require("postcss-flexbugs-fixes"),
require("postcss-nesting"),
require("postcss-custom-properties"),
require("autoprefixer"),
],
};
index.js
import "./styles/index.css";
import ExampleTestComponent from "./components/ExampleTestComponent";
...
export {
ExampleTestComponent,
...
}
ExampleTestComponent.js
import React from "react";
const ExampleTestComponent = (props) => {
return (
<div className="ExampleTestComponentClass">
--- This is a test ---
</div>
);
};
export default ExampleTestComponent;
index.css
#tailwind base;
#tailwind components;
#tailwind utilities;
Site Implementation
import ExampleTestComponent from "#github_account/package_name";
const HomePageTemplate = ({ heroItems, partners, newsItems, videos }) => {
const partnerItems = partners.map((partner) => ({
image: partner.logo,
url: partner.url,
}));
return (
<HomePageLayout heroItems={heroItems} partnerItems={partnerItems}>
<ExampleTestComponent />
<SuccessStoriesSlider videos={videos} />
<NewsBlock
newsItems={newsItems}
title="News"
subtitle="Latest news posts"
viewMoreBtnLabel="View Posts"
readMoreBtnLabel="Read More"
/>
</HomePageLayout>
);
};
export default HomePageTemplate;
UPDATE 1
Turns out a combination of using Yarn and adding the below
{
"resolutions": {
"postcss": "8"
}
}
to package.json, fixes the Postcss issue. So now I have the package created, I am attempting to import into the main site. However I'm now getting the error:
Error: Must use import to load ES Module: /node_modules/#github_account/package_name/node_modules/#babel/runtime/helpers/esm/defineProperty.js
require() of ES modules is not supported.
require() of /node_modules/#github_account/package_name/node_modules/#babel/runtime/helpers/esm/defineProperty.js from /node_modules/#github_account/package_name/build/main.cjs.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename defineProperty.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /node_modules/#github_account/package_name/node_modules/#babel/runtime/helpers/esm/package.json.
I installed a local .tgz package via npm "mdb-react-ui-kit": "file:mdb-react-ui-kit-4.0.0.tgz" (in my package.json). When I run npm run start. When running, I get an error from webpack saying it cannot resolve the .tgz file as it only looks in the node_modules folder. The file is stored in my project root folder.
How can I load this .tgz file correctly?
Error Message:
error message
Project Directory:
project directory
App.js:
import React from 'react';
import { MDBBtn, MDBContainer } from 'mdb-react-ui-kit';
function App() {
return (
<MDBContainer fluid>
<div
className='d-flex justify-content-center align-items-center'
style={{ height: '100vh' }}
>
<div className='text-center'>
<img
className='mb-4'
src='https://mdbootstrap.com/img/logo/mdb-transparent-250px.png'
style={{ width: 250, height: 90 }}
/>
<h5 className='mb-3'>
Thank you for using our product. We're glad you're with us.
</h5>
<p className='mb-3'>MDB Team</p>
<MDBBtn
tag='a'
href='https://mdbootstrap.com/docs/standard/getting-started/'
target='_blank'
role='button'
>
Start MDB tutorial
</MDBBtn>
</div>
</div>
</MDBContainer>
);
}
export default App;
Package.json:
{
"name": "mdb-react-template",
"version": "4.0.0",
"description": "template for mdb-react-ui-kit",
"private": true,
"dependencies": {
"history": "^5.3.0",
"mdb-react-ui-kit": "file:mdb-react-ui-kit-4.0.0.tgz",
"nodemon": "^2.0.18",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"#babel/core": "^7.12.3",
"#babel/plugin-transform-runtime": "^7.12.1",
"#babel/preset-env": "^7.12.1",
"#babel/preset-react": "^7.12.1",
"babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^5.2.7",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^4.5.0",
"imports-loader": "^4.0.0",
"postcss-loader": "^7.0.0",
"resolve-url-loader": "^5.0.0",
"sass-loader": "^13.0.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"webfontloader": "^1.6.28",
"webpack": "^5.4.0",
"webpack-cli": "^4.1.0",
"webpack-dev-server": "^4.9.1",
"webpack-merge": "^5.2.0"
},
...
}
}
Webpack.common.js:
const WebpackShellPlugin = require('webpack-shell-plugin')
const path = require('path');
module.exports = {
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-react', '#babel/preset-env'],
plugins: ['#babel/plugin-transform-runtime'],
},
},
},
{
test: /\.tgz$/,
enforce: 'pre',
use: 'raw-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(scss)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
},
]
},
],
},
resolve: {
alias: {
MDBPackage: path.resolve(__dirname, '../mdb-react-ui-kit-4.0.0.tgz'),
},
},
};
Webpack.dev.js:
const { merge } = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const commonConfig = require('./webpack.common');
const packageJson = require('../package.json');
const path = require('path');
const devConfig = {
mode: 'development',
output: {
publicPath: 'http://localhost:8090/', // don't forget the slash at the end
},
devServer: {
port: 8090,
historyApiFallback: {
index: 'index.html',
},
},
plugins: [
new ModuleFederationPlugin({
name: 'mdbReactMod',
filename: 'remoteEntry.js',
exposes: {
'./MDBReactApp': './src/bootstrap',
'./Tables': './src/components/table/CompanyUsersTable'
},
shared: packageJson.dependencies,
}),
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
};
module.exports = merge(commonConfig, devConfig);
I am having difficulty with resolving webpack deployment issue.
In development mode everything seems fine, but as I deployed this project through vercel, I am only getting blank screen. When I checked the page, nothing but index.html existed. (no other js files)
These are my files below. I really want to know what on earth the problem is.
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ReactRefreshWebpackPlugin = require('#pmmmwh/react-refresh-webpack-plugin');
const { ESBuildMinifyPlugin } = require('esbuild-loader');
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = () => ({
mode: isDevelopment ? 'development' : 'production',
devtool: isDevelopment ? 'eval-cheap-module-source-map' : false,
cache: { type: isDevelopment ? 'memory' : 'filesystem' },
entry: './src/index.tsx',
target: 'web',
output: {
filename: 'js/[name]-[chunkhash].js',
assetModuleFilename: 'img/[hash][ext][query]',
pathinfo: false,
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
clean: true,
},
resolve: {
alias: {
icons: path.resolve(__dirname, 'public/assets/icons'),
images: path.resolve(__dirname, 'public/assets/images'),
components: path.resolve(__dirname, 'src/components'),
data: path.resolve(__dirname, 'src/data'),
docs: path.resolve(__dirname, 'src/docs'),
pages: path.resolve(__dirname, 'src/pages'),
styles: path.resolve(__dirname, 'src/styles'),
types: path.resolve(__dirname, 'src/types'),
utils: path.resolve(__dirname, 'src/utils'),
},
extensions: ['*', '.js', '.tsx', '.ts'],
modules: [__dirname, 'src', 'node_modules'],
fallback: {
process: require.resolve('process/browser'),
zlib: require.resolve('browserify-zlib'),
stream: require.resolve('stream-browserify'),
util: require.resolve('util'),
buffer: require.resolve('buffer'),
assert: require.resolve('assert'),
},
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'esbuild-loader',
options: {
loader: 'tsx',
target: 'esnext',
},
},
{
test: /\.(png|jpg|svg|gif)$/,
type: 'asset/resource',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(ts|tsx)$/,
exclude: '/node_modules',
use: 'ts-loader',
},
{
test: /restructure(\/|\\)src(\/|\\)[\w]+.js/,
use: [
{
loader: 'imports-loader',
options: {
type: 'commonjs',
imports: 'multiple ../../buffer/ Buffer Buffer',
},
},
],
},
],
},
plugins: [
new HtmlWebpackPlugin({ template: './public/index.html' }),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser',
}),
new webpack.EnvironmentPlugin({
DEVELOPMENT: isDevelopment,
}),
isDevelopment && new webpack.HotModuleReplacementPlugin(),
isDevelopment && new ReactRefreshWebpackPlugin(),
],
optimization: {
minimize: !isDevelopment,
minimizer: [
new ESBuildMinifyPlugin({
target: 'esnext',
css: true,
}),
],
splitChunks: {
chunks: 'all',
},
},
externals: {
axios: 'axios',
},
devServer: {
port: 3000,
open: true,
hot: true,
historyApiFallback: true,
},
});
package.json
{
"name": "webpack",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"engines": {
"node": ">=16.15.0",
"yarn": ">=1.22.17"
},
"scripts": {
"build": "webpack",
"dev": "NODE_ENV=development & webpack serve --progress",
"build:dev": "NODE_ENV=development & yarn build",
"build:prod": "NODE_ENV=production & yarn build"
},
"keywords": [],
"devDependencies": {
"#pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
"#react-pdf/types": "^2.1.0",
"#types/react": "^18.0.12",
"#types/react-dom": "^18.0.5",
"#types/shortid": "^0.0.29",
"#types/styled-components": "^5.1.25",
"#typescript-eslint/eslint-plugin": "^5.27.1",
"#typescript-eslint/parser": "^5.27.1",
"css-loader": "^6.7.1",
"esbuild-loader": "^2.19.0",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.5.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"html-webpack-plugin": "^5.5.0",
"imports-loader": "^4.0.0",
"lodash": "^4.17.21",
"prettier": "^2.6.2",
"react-refresh": "^0.13.0",
"style-loader": "^3.3.1",
"ts-loader": "^9.3.0",
"typescript": "^4.7.3",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.2"
},
"dependencies": {
"#react-pdf/renderer": "^2.2.0",
"assert": "^2.0.0",
"axios": "^0.27.2",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"node-env": "^0.1.6",
"process": "^0.11.10",
"react": "^18.1.0",
"react-daum-postcode": "^3.1.1",
"react-dom": "^18.1.0",
"react-router-dom": "^6.3.0",
"shortid": "^2.2.16",
"stream-browserify": "^3.0.0",
"styled-components": "^5.3.5",
"styled-reset": "^4.4.1",
"util": "^0.12.4"
}
}
index.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import GlobalFont from 'styles/globalFont';
import GlobalStyle from 'styles/globalStyle';
import App from './App';
const rootEl = document.getElementById('root');
if (!rootEl) throw new Error('Failed to find the root element');
const root = createRoot(rootEl);
root.render(
<React.StrictMode>
<GlobalFont />
<GlobalStyle />
<App />
</React.StrictMode>,
);
App.tsx
import Home from 'pages/Home';
import PdfViewer from 'pages/PdfViewer';
import Test from 'pages/Test';
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/docs" element={<PdfViewer />} />
<Route path="/test" element={<Test />} />
</Routes>
</BrowserRouter>
);
}
export default App;
I've been stuck with this for a while trying to install and update. Finally, all the npm packages are in the latest version. Could you please let me know how I could get past this blocking error?
[ERROR] ERROR in multi react-hot-loader/patch event-source-polyfill webpack-hot-middleware/client?path=__webpack_hmr&dynamicPublicPath=true ./ClientApp/boot.tsx
Module not found: Error: Can't resolve 'react-hot-loader/webpack' in '...'
# multi react-hot-loader/patch event-source-polyfill webpack-hot-middleware/client?path=__webpack_hmr&dynamicPublicPath=true ./ClientApp/boot.tsx
Here's my webpack.config.js:
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const bundleOutputDir = './wwwroot/dist';
module.exports = (env) => {
const isDevBuild = !(env && env.prod);
return [{
stats: { modules: false },
entry: { 'main': './ClientApp/boot.tsx' },
resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
output: {
path: path.join(__dirname, bundleOutputDir),
filename: '[name].js',
publicPath: 'dist/'
},
module: {
rules: [
{ test: /\.tsx?$/, include: /ClientApp/, use: 'awesome-typescript-loader?silent=true' },
{ test: /\.css$/, use: isDevBuild ? ['style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader?minimize' }) },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' },
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader"
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader"
}
]
},
plugins: [
new CheckerPlugin(),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin('site.css')
])
}];
};
Here is the package.json so that the versions of the packages that I'm using are shown below:
{
"name": "MyProject",
"private": true,
"version": "0.0.0",
"devDependencies": {
"#types/history": "4.6.2",
"#types/react": "^16.4.1",
"#types/react-dom": "16.0.6",
"#types/react-hot-loader": "4.1.0",
"#types/react-router": "4.0.27",
"#types/react-router-dom": "4.2.7",
"#types/react-table": "^6.7.11",
"#types/webpack-env": "1.13.6",
"aspnet-webpack": "^3.0.0",
"aspnet-webpack-react": "^3.0.0",
"awesome-typescript-loader": "5.2.0",
"bootstrap": "4.1.1",
"css-loader": "0.28.11",
"event-source-polyfill": "0.0.12",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.11",
"isomorphic-fetch": "2.2.1",
"jquery": "3.3.1",
"json-loader": "0.5.7",
"react": "16.4.1",
"react-dom": "^16.4.1",
"react-hot-loader": "^4.3.3",
"react-router-dom": "4.3.1",
"style-loader": "0.21.0",
"typescript": "2.9.2",
"url-loader": "1.0.1",
"webpack": "^4.12.2",
"webpack-dev-middleware": "^3.1.3",
"webpack-dev-server": "^3.1.4",
"webpack-hot-middleware": "^2.22.2"
},
"dependencies": {
"#types/react-fontawesome": "^1.6.3",
"ajv": "^6.5.1",
"classnames": "^2.2.6",
"font-awesome": "^4.7.0",
"get-latest": "^0.1.0",
"latest-version": "^4.0.0",
"npm": "^6.1.0",
"npm-install-peers": "^1.2.1",
"popper.js": "^1.14.3",
"react-table": "^6.8.6",
"update-all-packages": "^1.0.2"
}
}
I get the following error when running webpack:
Error in ./src/index.jsx
Module parse failed: .../src/index.jsx Unexpected token (10:18)
You may need an appropriate loader to handle this file type.
I believe I have all the correct loaders set up, please tell me if I missed something.
package.json:
"dependencies": {
"isomorphic-fetch": "^2.2.1",
"koa": "^1.2.4",
"koa-ejs": "^3.0.0",
"koa-route": "^2.4.2",
"koa-router": "^5.4.0",
"koa-static": "^2.0.0",
"koa-webpack-dev-middleware": "^1.2.2",
"node-sass": "^3.10.1",
"react": "^15.3.2",
"react-dom": "^15.3.2",
"react-hot-loader": "^1.3.0",
"react-redux": "^4.4.5",
"react-router": "^2.8.1",
"redux": "^3.6.0",
"redux-thunk": "^2.1.0",
"sass-loader": "^4.0.2",
"style-loader": "^0.13.1",
"webpack": "^1.13.2"
},
"devDependencies": {
"babel-core": "^6.17.0",
"babel-eslint": "^7.0.0",
"babel-loader": "^6.2.6",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-0": "^6.16.0",
"babel-preset-react-hmre": "^1.1.1",
"css-loader": "^0.25.0",
"eslint": "^3.7.1",
"eslint-loader": "^1.5.0",
"eslint-plugin-react": "^6.4.1",
"koa-webpack-hot-middleware": "^1.0.3",
"react-hot-loader": "^1.3.0",
"redux-devtools": "^3.3.1",
"webpack-dev-server": "^1.16.2"
}
webpack.config.js:
const webpack = require('webpack');
const path = require('path');
const ROOT_PATH = path.resolve(__dirname);
module.exports = {
devtool: process.env.NODE_ENV === 'production' ? '' : 'source-map',
entry: [
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000',
path.resolve(ROOT_PATH, 'src/index.jsx')
],
module: {
preLoaders: [{
test: /\.jsx?$/,
loaders: process.env.NODE_ENV === 'production' ? [] : ['eslint'],
include: path.resolve(ROOT_PATH, 'src/index.jsx')
}],
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-0', 'react'],
cacheDirectory: true,
env: {
development: {
presets: ['react-hmre']
}
}
},
include: './src'
},
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
output: {
path: process.env.NODE_ENV === 'production'
? path.resolve(ROOT_PATH, 'dist')
: path.resolve(ROOT_PATH, 'build'),
publicPath: '/',
filename: 'bundle.js'
},
devServer: {
contentBase: path.resolve(ROOT_PATH, 'build'),
historyApiFallback: true,
hot: true,
inline: true,
progress: true
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
};
src/index.jsx:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
const main = () => {
const app = document.createElement('div');
document.body.appendChild(app);
ReactDOM.render(<App />, app);
};
main();
I have also tried without any presets using a .babelrc file:
{
"presets": ["es2015", "stage-0", "react"]
}
Running babel src/index.jsx does work as expected, so I think this is an issue with the webpack configuration.
My include path for the js(x) loader was wrong. Fixed using
include: path.resolve(ROOT_PATH, './src')
instead of
include: './src'