I switched my NextJS app to SWC (I removed Babel`s config, and enabled the emotion plugin).
Now, I see that build time has increased from 80 s to ~200 s.
Does anyone have a similar experience?
My next.config.js:
// #ts-check
const path = require('path')
const _ = require('lodash')
const withBundleAnalyzer = require('#next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
const withImages = require('next-optimized-images')
const withFonts = require('next-fonts')
const withTM = require('next-transpile-modules')([
'#xxx/helpers',
'#xxx/ui',
'#xxx/api',
])
console.log('basePath -', process.env.BASE_PATH)
console.log(`Fs cache ${process.env.ENABLE_FS_CACHE ? 'enabled' : 'disabled'}`)
/**
* Filters out keys with undefined value to be compliant with Next's env type definition
* #param {{ [key: string]: string | undefined }} envs
* #returns {{ [key: string]: string}}
*/
const getEnvs = (envs) => {
/** #type {{ [key: string]: string}} */
const result = {}
Object.entries(envs).forEach(([key, env]) => {
if (env) result[key] = env
})
return result
}
/**
* #type {import('next').NextConfig}
*/
const settings = {
env: getEnvs({
...
}),
trailingSlash: true,
poweredByHeader: false,
basePath: process.env.BASE_PATH,
baseUrl: process.env.BASE_URL,
assetPrefix: process.env.ASSET_PREFIX,
esModule: true,
handleImages: ['jpeg', 'png', 'webp', 'gif'],
// #ts-ignore fix images config to match next types. We need to extract images sizes from test setup
images: {
disableStaticImages: true,
domains: ['images.ctfassets.net'],
loader: 'custom',
},
eslint: {
ignoreDuringBuilds: true,
},
experimental: {
emotion: true,
},
swcMinify: true,
distDir: 'dist',
webpack: (config, { isServer }) => {
config.module.rules.push({
test: /\.svg$/,
use: [
{
loader: '#svgr/webpack',
options: {
svgoConfig: {
plugins: [
{
name: 'removeViewBox',
active: false,
},
{ name: 'cleanupIDs', active: false },
{ name: 'prefixIds', active: true },
],
},
},
},
'url-loader',
],
})
config.module.rules.push({
test: /\.mp4$/,
use: [
{
loader: 'file-loader',
options: {
publicPath: `${process.env.ASSET_PREFIX || ''}/_next/static/videos/`,
outputPath: `${config.isServer ? '../' : ''}static/videos/`,
name: '[name]-[hash].[ext]',
},
},
],
})
config.module.rules.push({
test: /\.json(.*?)\.data$/,
use: [
{
loader: 'file-loader',
options: {
publicPath: `${process.env.ASSET_PREFIX || ''}/_next/static/data/`,
outputPath: `${config.isServer ? '../' : ''}static/data/`,
name: '[name]-[hash].json',
},
},
],
})
if (!isServer) {
config.resolve.fallback.fs = false
config.resolve.fallback.path = false
config.resolve.fallback.crypto = false
config.resolve.fallback.readline = false
}
return config
},
}
const enhanceConfig = _.flow([withImages, withFonts, withBundleAnalyzer, withTM])
module.exports = enhanceConfig(settings)
Related
I have set productionBrowserSourceMaps: true in next.config.js.
Full next.config.js
const { withRNV } = require('#rnv/engine-rn-next');
const path = require('path');
const fs = require('fs');
const cp = require('child_process');
const config = {
compress: false,
webpack: (cfg, { isServer }) => {
if (!isServer) cfg.resolve.alias['#sentry/node'] = '#sentry/browser';
cfg.module.rules.push({
test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 100000,
name: '[name].[ext]',
},
},
});
return cfg;
},
typescript: {
ignoreBuildErrors: true,
},
publicRuntimeConfig: {
deployEnv: process.env.DEPLOY_ENV || 'Development',
customScripts: [],
},
images: {
loader: 'akamai',
path: '',
},
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'X-Application-Version',
value: getPackageVersion(),
},
{
key: 'access-control-allow-origin',
value: '*',
},
],
},
];
},
experimental: {
outputStandalone: true,
},
productionBrowserSourceMaps: true,
};
module.exports = withRNV(config, {
enableNextCss: false,
enableOptimizedImages: true,
});
But in sources i see this ES5 code:
I don't see original ES6 source code.
How should I set config to see it?
This is my babel.config.js
const { withRNVBabel } = require('rnv');
const fs = require('fs');
const resolveObj = {
alias: {},
};
if (process.env.NEXT_ENV === 'prod') {
resolveObj.root = ['.'];
} else {
resolveObj.root = ['../..'];
}
const config = {
retainLines: true,
ignore: [/#babel[/\\]runtime/],
presets: ['module:babel-preset-expo'],
plugins: [
'styled-jsx/babel',
[
'module:react-native-dotenv',
{
moduleName: '#env',
path: '.env',
},
],
],
};
let finalConfig;
if (!fs.existsSync(process.env.RNV_ENGINE_PATH)) {
config.plugins.push([require.resolve('babel-plugin-module-resolver'), resolveObj]);
finalConfig = config;
} else {
finalConfig = withRNVBabel(config);
}
module.exports = finalConfig;
I'm using the following WordPress starter plugin with a full working Vue configuration implemented: https://github.com/tareq1988/vue-wp-starter
This plugin works in general. But seems that there is a Webpack issue which is responsible to generate some css files.
This is the Webpack configuration:
const webpack = require("webpack");
const path = require("path");
const package = require("./package.json");
const { VueLoaderPlugin } = require("vue-loader");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const BrowserSyncPlugin = require("browser-sync-webpack-plugin");
const TerserJSPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const config = require("./config.json");
const devMode = process.env.NODE_ENV !== "production";
// Naming and path settings
var appName = "app";
var entryPoint = {
frontend: "./src/frontend/main.js",
admin: "./src/admin/main.js",
style: ['./assets/less/style.less', './assets/scss/style.scss'],
};
var exportPath = path.resolve(__dirname, "./assets/js");
// Enviroment flag
var plugins = [];
// extract css into its own file
plugins.push(
new MiniCssExtractPlugin({
filename: "../css/[name].css",
ignoreOrder: true
})
);
plugins.push(
new webpack.DefinePlugin({
__VUE_OPTIONS_API__: false,
__VUE_PROD_DEVTOOLS__: false,
}),
)
// enable live reload with browser-sync
// set your WordPress site URL in config.json
// file and uncomment the snippet below.
// --------------------------------------
// plugins.push(new BrowserSyncPlugin( {
// proxy: {
// target: config.proxyURL
// },
// files: [
// '**/*.php'
// ],
// cors: true,
// reloadDelay: 0
// } ));
plugins.push(new VueLoaderPlugin());
// Differ settings based on production flag
if (devMode) {
appName = "[name].js";
} else {
appName = "[name].min.js";
}
module.exports = {
entry: entryPoint,
mode: devMode ? "development" : "production",
output: {
path: exportPath,
filename: appName,
},
resolve: {
alias: {
vue$: "vue/dist/vue.esm-bundler.js",
"#": path.resolve("./src/"),
frontend: path.resolve("./src/frontend/"),
admin: path.resolve("./src/admin/"),
},
modules: [
path.resolve("./node_modules"),
path.resolve(path.join(__dirname, "src/")),
],
},
optimization: {
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\\/]node_modules[\\\/]/,
name: "vendors",
chunks: "all",
},
},
},
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
plugins,
module: {
rules: [
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.js$/,
use: "babel-loader",
exclude: /node_modules/,
},
{
test: /\.less$/,
use: ['vue-style-loader', "css-loader", "less-loader"],
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.png$/,
use: [
{
loader: "url-loader",
options: {
mimetype: "image/png",
},
},
],
},
{
test: /\.svg$/,
use: "file-loader",
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
return path.relative(path.dirname(resourcePath), context) + "/";
},
hmr: process.env.NODE_ENV === "development",
},
},
"css-loader",
],
},
],
},
};
This is the folder structure for the relevant part:
Starting the app with npm run dev I get no error messages. But I expect the files /assets/css/admin.css and /assets/css/frontend.css to automatically be created. This is what the developer says here:
Also the paths are included in the related PHP files for WordPress (includes/Assets.php):
So I get the following 404 error:
....plugin-root/assets/css/admin.css?ver=0.1.0 net::ERR_ABORTED 404 (Not Found)
Long description in short: The configurator for this starter plugin should generate two css files which are missing. What could be the reason for this? Do I miss something?
For some reason when i look at the Docs for a story the args comes out at the top of the page, it suppose to come out inside the arg control table.
see image below
webpack.config.js
const path = require("path");
const babelSettings = require("../babel.config.js");
module.exports = async ({ config, mode }) => {
config.resolve.modules.push(path.resolve(__dirname, "../lib"));
config.resolve.extensions.push(".ts");
config.resolve.extensions.push(".tsx");
config.module.rules.push(
{
test: /\.(ts|tsx)$/,
use: {
loader: "babel-loader",
options: {
presets: babelSettings.presets,
plugins: babelSettings.plugins,
cacheDirectory: true,
},
},
}
)
config.module.rules.push(
{
test: /\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: {
auto: true,
localIdentName: "[name]__[local]--[hash:base64:5]",
},
},
},
{
loader: "sass-loader",
options: {
sassOptions: {
includePaths: ["lib"],
},
},
},
],
include: path.resolve(__dirname, "../"),
},
);
return config;
};
main.ts
const path = require("path");
module.exports = {
addons: [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/addon-a11y",
"storybook-addon-designs",
"storybook-css-modules-preset",
"#storybook/addon-storysource",
],
stories: [
"../lib/intro.stories.mdx",
"../lib/started.stories.mdx",
"../lib/**/*.stories.#(mdx)",
"../lib/**/*.stories.#(js|ts|tsx)"
],
typescript: {
check: true,
checkOptions: {
tsconfig: path.resolve(__dirname, "../tsconfig.json"),
eslint: true,
},
reactDocgen: "react-docgen-typescript",
reactDocgenTypescriptOptions: {
stsconfigPath: path.resolve(__dirname, "../tsconfig.json"),
},
},
};
preview.ts
import { DocsPage, DocsContainer } from "#storybook/addon-docs/blocks";
import { configure } from "#storybook/react";
import "../scss/styles.scss";
export const parameters = {
controls: { expanded: true },
actions: { argTypesRegex: "^on[A-Z].*" },
a11y: {
element: "#root",
manual: false,
},
docs: {
container: DocsContainer,
page: DocsPage,
},
};
configure(require.context("../", true, /\.stories\.(ts|tsx|mdx)$/), module);
field.stories.tsx
import React from "react";
import { withDesign } from "storybook-addon-designs";
import ReadOnlyField from ".";
export default {
title: "Form/Field",
component: ReadOnlyField,
parameters: {
componentSubtitle: "Displays a field that a user is not able to change its value",
actions: {
table: {
disable: true,
},
},
},
decorators: [withDesign],
argTypes: {
id: {
control: {
disable: true,
},
},
extraClasses: {
control: {
disable: true,
},
},
},
};
export const Basic = (args: { label: string, body: string }): JSX.Element => <ReadOnlyField
id="read-only-field" body={args.body} label={args.label} />;
Basic.args = {
label: "Email Address",
body: "test#test.com",
};
i am using css module to style my components. looks like one of my classes what updated the textfield's styles.
I am new to webpack and react, i downloaded one github project which suits my requirement and when i start my server, i see that css is not getting included in build html file.
'use strict';
const fs = require('fs');
const path = require('path');
const resolve = require('resolve');
const webpack = require('webpack');
const PnpWebpackPlugin = require('pnp-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const getClientEnvironment = require('./env');
const paths = require('./paths');
const ManifestPlugin = require('webpack-manifest-plugin');
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin-alt');
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
const publicPath = '/';
const publicUrl = '';
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);
// Check if TypeScript is setup
const useTypeScript = fs.existsSync(paths.appTsConfig);
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
],
},
},
];
if (preProcessor) {
loaders.push(require.resolve(preProcessor));
}
return loaders;
};
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
entry: [
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appIndexJs,
paths.appBuild + '/static/css/main.chunk.css',
],
output: {
pathinfo: true,
filename: 'static/js/bundle.js',
chunkFilename: 'static/js/[name].chunk.js',
publicPath: publicPath,
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
},
optimization: {
splitChunks: {
chunks: 'all',
name: false,
},
runtimeChunk: true,
},
resolve: {
modules: ['node_modules'].concat(
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
),
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')),
alias: {
// 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',
'actions': path.resolve(__dirname, '../src/actions'),
'constants': path.resolve(__dirname, '../src/constants'),
'containers': path.resolve(__dirname, '../src/components/containers'),
'commons': path.resolve(__dirname, '../src/components/common'),
'reducers': path.resolve(__dirname, '../src/reducers'),
'domains': path.resolve(__dirname, '../src/domains'),
'libs': path.resolve(__dirname, '../src/libs')
},
plugins: [
PnpWebpackPlugin,
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
resolveLoader: {
plugins: [
PnpWebpackPlugin.moduleLoader(module),
],
},
module: {
strictExportPresence: true,
rules: [
{ parser: { requireEnsure: false } },
{
test: /\.(js|mjs|jsx)$/,
enforce: 'pre',
use: [
{
options: {
formatter: require.resolve('react-dev-utils/eslintFormatter'),
eslintPath: require.resolve('eslint'),
},
loader: require.resolve('eslint-loader'),
},
],
include: paths.appSrc,
},
{
oneOf: [
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
},
},
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent: '#svgr/webpack?-prettier,-svgo![path]',
},
},
},
],
],
cacheDirectory: true,
// Don't waste time on Gzipping the cache
cacheCompression: false,
},
},
{
test: /\.(js|mjs)$/,
exclude: /#babel(?:\/|\\{1,2})runtime/,
loader: require.resolve('babel-loader'),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
cacheDirectory: true,
cacheCompression: false,
sourceMaps: false,
},
},
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
}),
},
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
}),
},
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders({ importLoaders: 2 }, 'sass-loader'),
},
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
},
'sass-loader'
),
},
{
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
loader: require.resolve('file-loader'),
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml
}),
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
new ModuleNotFoundPlugin(paths.appPath),
new webpack.DefinePlugin(env.stringified),
new webpack.HotModuleReplacementPlugin(),
new CaseSensitivePathsPlugin(),
new WatchMissingNodeModulesPlugin(paths.appNodeModules),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new ManifestPlugin({
fileName: 'asset-manifest.json',
publicPath: publicPath,
}),
// TypeScript type checking
useTypeScript &&
new ForkTsCheckerWebpackPlugin({
typescript: resolve.sync('typescript', {
basedir: paths.appNodeModules,
}),
async: false,
checkSyntacticErrors: true,
tsconfig: paths.appTsConfig,
compilerOptions: {
module: 'esnext',
moduleResolution: 'node',
resolveJsonModule: true,
isolatedModules: true,
noEmit: true,
jsx: 'preserve',
},
reportFiles: [
'**',
'!**/*.json',
'!**/__tests__/**',
'!**/?(*.)(spec|test).*',
'!src/setupProxy.js',
'!src/setupTests.*',
],
watch: paths.appSrc,
silent: true,
formatter: typescriptFormatter,
}),
].filter(Boolean),
node: {
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
performance: false,
};
i am just clueless where to edit above code to solve my problem, i also observed that css in build folder has '#' at the beginning
Project build folder image
I think you'll need to add a css loader to your plugins. You'll have to
npm install css-loader style-loader --save-dev
Add a plugin to to your webpack.config.js
module:{
rules:[
// other plugins
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
}
Now webpack should bundle your css properly. Note you have to make sure you have imported you css file into your application !
import '../app.css';
Run webpack again and you should see the css inserted in s style tag in the header of your html page
I'm trying to setup a project with react that uses a combination of scss (mixins, variables, etc) and css modules.
However when I setup up webpack using style-loader, css-loader, postcss-loader, sass-loader, sass-resources-loader, import-glob-loader. I get an error that is the following:
Worker error Error: Unexpected token string «./node_modules/css-
loader/index.js?"importLoaders":1,"modules":true,"localIdentName"
:"[name]__[local]___[hash:base64:5]"!./node_modules/postcss-loade
r/lib/index.js?!./node_modules/sass-loader/lib/loader.js!./node_m
odules/sass-resources-loader/lib/loader.js?"resources":["/Users/*
***/Documents/Repos/project/src/scss/*.scss"]!./node_modules/impo
rt-glob-loader/index.js!./src/App/App.scss», expected punc «,»
at objectToError (/Users/****/Documents/Repos/project/node_mo
dules/workerpool/lib/WorkerHandler.js:63:14)
at ChildProcess.<anonymous> (/Users/****/Documents/Repos/ui-
kit/node_modules/workerpool/lib/WorkerHandler.js:146:32)
at emitTwo (events.js:125:13)
at ChildProcess.emit (events.js:213:7)
at emit (internal/child_process.js:774:12)
at _combinedTickCallback (internal/process/next_tick.js:141:1
1)
at process._tickCallback (internal/process/next_tick.js:180:9
) filename: '0', line: 18, col: 936, pos: 2292
Webpack Scss
const webpack = require('webpack');
const path = require('path');
const DashboardPlugin = require('webpack-dashboard/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer');
const nodeEnv = process.env.NODE_ENV || 'development';
const isProduction = nodeEnv === 'production';
const jsSrcPath = path.join(__dirname, './');
const publicPath = path.join(__dirname, './public');
const imgPath = path.join(__dirname, './src/assets/img');
const srcPath = path.join(__dirname, './src');
/* Common plugins */
const plugins = [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(nodeEnv)
}
}),
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
template: path.join(publicPath, 'index.html'),
path: publicPath,
filename: 'index.html',
}),
new webpack.NoEmitOnErrorsPlugin(),
];
/* Common Rules */
const rules = [{
test: /\.(js|jsx)$/,
include: path.join(__dirname, 'src'),
exclude: path.resolve(__dirname, "node_modules"),
loader: "babel-loader"
},
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
localIdentName: "[name]__[local]___[hash:base64:5]"
}
},
{
loader: 'postcss-loader',
options: {
plugins: () => [autoprefixer]
}
},
'sass-loader',
{
loader: 'sass-resources-loader',
options: {
resources: [
path.resolve(__dirname, "./src/scss/*.scss")
]
}
},
'import-glob-loader'
]
},
{
test: /\.woff$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff&name=[path][name].[ext]"
}, {
test: /\.woff2$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff2&name=[path][name].[ext]"
},
{
test: /\.(png|gif|jpg|svg)$/,
include: imgPath,
use: 'url-loader?limit=20480&name=assets/[name]-[hash].[ext]',
}
];
if (isProduction) {
// Production plugins
plugins.push(
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false,
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
},
output: {
comments: false,
},
}),
);
// Production rules
} else {
// Development plugins
plugins.push(
new webpack.HotModuleReplacementPlugin(),
new DashboardPlugin()
);
// Development rules
}
module.exports = {
devtool: isProduction ? 'eval' : 'source-map',
context: jsSrcPath,
entry: [
'babel-polyfill',
'./src/index.js'
],
output: {
path: publicPath,
publicPath: '/',
filename: 'app-[hash].js',
},
module: {
rules,
},
resolve: {
extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx'],
modules: [
path.resolve(__dirname, "node_modules"),
jsSrcPath
]
},
plugins,
devServer: {
contentBase: isProduction ? './public' : './src',
historyApiFallback: true,
port: 3000,
compress: isProduction,
inline: !isProduction,
hot: !isProduction,
host: '0.0.0.0',
stats: {
assets: true,
children: false,
chunks: false,
hash: false,
modules: false,
publicPath: false,
timings: true,
version: false,
warnings: true,
colors: {
green: '\u001b[32m'
}
}
}
};
react:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import styles from './App.scss';
class App extends Component {
render() {
return (
<div>
<h1 className={styles.main}>Hello World</h1>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
app: state.app
};
};
export default connect(mapStateToProps, null)(App)
App.scss file
.main { color: red; }
Anyone else have this issue before?
It appears your exclude: path.resolve(__dirname, "node_modules"), to be blamed. Can you try after removing that from the loaders ?
To give you more insight: the error is reporting something about node_modules/css-loader/index.js. A java script file. In your js|jsx rule (i.e. babel-loader) you are excluding node_modules entirely. That is the problem cause.
UPDATE : issue cause code
Full for reference
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.scss$/,
loader: ExtractPlugin.extract(['css-loader', 'sass-loader']),
},
{
test: /\.css$/,
exclude: [/\.global\./, /node_modules/],
loader: ExtractPlugin.extract(
{
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
autoprefixer: true,
minimize: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}
]
})
},
Still not 100% sure why this works but I added extract-text-plugin and it fixed my issues.
{
test: /\.s?css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
plugins: () => [autoprefixer]
}
},
'sass-loader'
]
})
}
also add new ExtractTextPlugin({ filename: '[name].css' }), to plugins