Compiling SASS files with Webpack - javascript

I want to use webpack so that it will automatically compile any and all .scss files in my /src/app folder into a single .css file without me having to explicity point to all of the .scss files / import them.
I am trying to use ExtractTextPlugin to do this but it does not seem to be working. Do I need to provide a more specific entry point? Are my loaders not configured correctly? Or is there something else wrong? Thanks!
webpack.config.js:
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const DIST_DIR = path.resolve(__dirname, "dist");
const SRC_DIR = path.resolve(__dirname, "src");
const config = {
devtool: 'inline-source-map',
entry: [
"babel-polyfill",
SRC_DIR + "/app/index.js"
SRC_DIR + "/app/"
],
target: 'web',
output: {
path: DIST_DIR + "/app/",
filename: "bundle.js",
publicPath: "/app/"
},
devServer: {
contentBase: './dist',
historyApiFallback: true,
hot: true,
proxy: {
'/api': {
target: 'http://localhost:5001',
secure: false,
},
}
},
plugins: [
new ExtractTextPlugin({filename: "foo.css", allChunks: true})
],
module: {
rules: [
{
enforce: "pre",
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
options: {
failOnWarning: false,
failOnError: true
}
},
{
test: /\.js$/,
include: SRC_DIR,
loader: 'babel-loader',
query: {
presets: ['react', 'stage-2']
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: 'css-loader?importLoaders=1',
})
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract(['css-loader', 'sass-loader']),
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: ['file-loader?context=src/images&name=images/[path][name].[ext]', {
loader: 'image-webpack-loader',
query: {
mozjpeg: {
progressive: true,
},
gifsicle: {
interlaced: false,
},
optipng: {
optimizationLevel: 7,
},
pngquant: {
quality: '75-90',
speed: 3,
},
},
}],
exclude: path.resolve(__dirname, "node_modules"),
include: __dirname,
},
{
test: /\.woff2?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
// loader: "url?limit=10000"
use: "url-loader"
},
{
test: /\.(ttf|eot|svg)(\?[\s\S]+)?$/,
use: 'file-loader'
},
]
},
};
module.exports = config;
package.json
{
"name": "",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "jest",
"watch": "webpack --progress --watch",
"start": "yarn build",
"build": "webpack -d && cp src/index.html dist/index.html && webpack-dev-server --inline --hot --history-api-fallback",
"build:dev": "webpack && cp src/index.html dist/index.html",
"build:prod": "webpack -p && cp src/index.html dist/index.html"
},
"author": "",
"license": "UNLICENSED",
"devDependencies": {
"babel-cli": "7.0.0-beta.3",
"babel-eslint": "7",
"babel-loader": "^7.1.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"css-loader": "^0.28.7",
"enzyme": "^3.1.0",
"enzyme-adapter-react-16": "^1.0.1",
"eslint": "3.x",
"eslint-config-airbnb": "^15.1.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.4.0",
"extract-text-webpack-plugin": "^3.0.0",
"fetch-mock": "^6.0.0-beta.7",
"file-loader": "^0.11.2",
"image-webpack-loader": "^3.4.2",
"jest": "^23.1.0",
"jest-enzyme": "^4.0.0",
"jest-fetch-mock": "^1.6.4",
"node-sass": "^4.9.0",
"redux-mock-store": "^1.5.3",
"sass-loader": "^6.0.6",
"url-loader": "^0.5.9",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1"
},
"dependencies": {
"#trendmicro/react-toggle-switch": "^0.5.7",
"babel-polyfill": "^6.26.0",
"cross-fetch": "^1.1.1",
"font-awesome": "^4.7.0",
"highcharts": "^6.0.4",
"history": "^4.7.2",
"js-cookie": "^2.2.0",
"less-loader": "^4.0.5",
"libphonenumber-js": "^0.4.42",
"lodash": "^4.17.4",
"moment": "^2.19.1",
"prop-types": "^15.6.0",
"query-string": "^5.0.1",
"rc-time-picker": "^3.1.0",
"react": "^16.0.0",
"react-animations": "^1.0.0",
"react-autosuggest": "^9.3.4",
"react-circular-progressbar": "^0.8.0",
"react-datepicker": "^0.59.0",
"react-dom": "^16.0.0",
"react-highcharts": "^15.0.0",
"react-list": "^0.8.8",
"react-redux": "^5.0.6",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-router-redux": "^5.0.0-alpha.6",
"react-select": "^1.0.0-rc.10",
"react-transition-group": "^1.2.0",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.2.0",
"styled-components": "3.2.3",
"twilio-client": "^1.4.33"
},
"jest": {
"setupTestFrameworkScriptFile": "./node_modules/jest-enzyme/lib/index.js"
}
}

without me having to explicity point to all of the .scss files /
import them.
You can't do that, webpack is not like gulp or other task runner that you can just point patterns and it will apply transformations to them.
Webpack works with dependency graphs, and these graphs are going to start from your entry points. On each entrypoint it reads the dependencies and apply those loaders specified for each file extension. Webpack only knows the existence of that file, if it is imported in any file that is part of the dependency graph.
If you want to transform css the way that you described, i suggest you moving towards a more task runner library such as gulp.

Related

Published npm package does not apply styles

I'm currently working on creating an npm package. Which is basically a React component with added styles using SCSS. When I test it out, the class names are there, but no styles are being applied.
Here is the repo for the package. I use a separated webpack config for building the specific folder where the component is.
Here's the webpack configuration I'm using:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const EsLintFormatter = require('eslint-formatter-pretty');
const path = require('path');
const pkg = require('../../package.json');
const { SRC_PATH, BUILD_PATH } = require('./constants');
const setStyleLoaders = require('./style-loaders');
const alias = require('./alias');
const packageName = pkg.name;
module.exports = ({ NODE_ENV }) => ({
mode: 'production',
entry: `${SRC_PATH}/components/Carousel/Carousel.js`,
output: {
path: BUILD_PATH,
filename: 'index.js',
library: packageName,
libraryTarget: 'commonjs2',
umdNamedDefine: true,
publicPath: '/build/',
},
node: {
net: 'empty',
tls: 'empty',
dns: 'empty',
},
resolve: {
alias: {
...alias,
react: path.resolve(__dirname, './node_modules/react'),
'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
},
},
externals: {
react: 'react',
reactDom: 'react-dom',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: [
{ loader: 'babel-loader' },
{
loader: 'eslint-loader',
options: {
formatter: EsLintFormatter,
},
},
],
},
{
test: /\.(sa|sc|c)ss$/,
use: setStyleLoaders(NODE_ENV),
},
{
test: /\.(png|pje?g|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'images',
},
},
],
},
{
test: /\.(woff|woff2|tff|otf|eot)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'fonts',
},
},
],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({ filename: 'index.css' }),
],
});
...and here's my package.json
{
"name": "react-clear-carousel",
"version": "0.1.0-beta.1",
"description": "A test",
"main": "build/index.js",
"scripts": {
"start": "cross-env NODE_ENV=development webpack-dev-server --env.NODE_ENV=development --config config/webpack/webpack.config.js",
"build": "cross-env NODE_ENV=production webpack --env.NODE_ENV=production --config config/webpack/webpack.config.publish.js",
"stylelint": "stylelint 'src/**/*.scss' --config stylelint.config.js; exit 0",
"eslint": "eslint 'src/**/*.js'; exit 0",
"es:fix": "eslint 'src/**/*.js' --fix",
"style:fix": "stylelint 'src/**/*.scss' --fix",
"lint": "npm run eslint && npm run stylelint",
"publish:beta": "npm publish --tag=beta",
"test": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/RobCC/web-playground.git"
},
"author": "robcc",
"license": "ISC",
"bugs": {
"url": "https://github.com/RobCC/web-playground/issues"
},
"files": [
"dist"
],
"jest": {
"setupFilesAfterEnv": [
"<rootDir>/config/jest/setup.js"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/config/jest/fileMock.js",
"\\.(css|less|scss)$": "identity-obj-proxy",
"^~/(.*)": "<rootDir>/$1",
"^#/(.*)": "<rootDir>/src/$1"
}
},
"homepage": "https://github.com/RobCC/web-playground#readme",
"peerDependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1",
"prop-types": "^15.7.2"
},
"devDependencies": {
"#babel/cli": "^7.8.4",
"#babel/core": "^7.9.0",
"#babel/plugin-proposal-class-properties": "^7.8.3",
"#babel/plugin-proposal-export-default-from": "^7.8.3",
"#babel/plugin-proposal-export-namespace-from": "^7.8.3",
"#babel/preset-env": "^7.9.0",
"#babel/preset-react": "^7.9.1",
"#types/jest": "^25.1.4",
"#types/node": "^13.9.2",
"#types/react": "^16.9.25",
"#types/react-dom": "^16.9.5",
"#welldone-software/why-did-you-render": "^4.0.5",
"autoprefixer": "^9.7.4",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0",
"chalk": "^3.0.0",
"clean-webpack-plugin": "^3.0.0",
"core-js": "^3.6.4",
"cross-env": "^7.0.2",
"css-loader": "^3.4.2",
"cssnano": "^4.1.10",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.1.0",
"eslint-formatter-pretty": "^3.0.1",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-loader": "^3.0.3",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^2.5.1",
"file-loader": "^6.0.0",
"html-webpack-plugin": "^3.2.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^25.1.0",
"log-symbols": "^3.0.0",
"mini-css-extract-plugin": "^0.9.0",
"postcss-loader": "^3.0.0",
"pr*op-types": "^15.7.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"regenerator-runtime": "^0.13.5",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3",
"stylelint": "^13.2.1",
"stylelint-config-recommended": "^3.0.0",
"stylelint-formatter-pretty": "^2.0.0",
"stylelint-scss": "^3.16.0",
"stylelint-webpack-plugin": "^1.2.3",
"ts-loader": "^6.2.1",
"typescript": "^3.8.3",
"webpack": "^4.42.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"dependencies": {
"weak-key": "^1.0.2"
}
}
This is the result when testing the published package:
Edit 1:
There are no errors on the Network and Console tab in devtools. I also can't find the file loaded, even though it's there in the package. It seems like the js file is not using it, but it should.
Edit 2:
Thanks for pointing me on the right direction!
I added import 'react-clear-carousel/build/index.css'; to include the CSS file from my package. I can see the file now (on devtools), but the styles are not being applied since css-loader is modularizing it and adding additional suffix and prefix (even though it already had them), thus having different class names that the ones my component has.
eg. My component is rendered as <div class="carousel_swimlane--kXSjh">, but the styles in the DOM are named as index_carousel_swimlane--kXSjh--2C.
I guess the question is now, how do I tell Webpack to pass this CSS as is? And if there's a way for me to deliver the CSS file without other people having to change their Webpack configuration.
Looking at your repo I see that you are importing your scss but attributing it's properties to classNames.
className should be the name of the class, and you can either attribute your imported styles to style or you can load your compiled css into the DOM using <link rel="stylesheet" type="text/css" href="styles.min.css">
The reason you're not seeing a stylesheet in the network tab is because you've simply forgotten to declare a stylesheet.

3rd party Javascript and CSS files in Webpack. Strange behaviour

I am using the MERN stack. I had to use a 3rd party html admin template which has a lot of standard js and css files (jquery, bootstrap, datatables etc.). To integrate it with react, I created a "public" folder in the root directory of my project. I then configured Express to serve this folder as a static folder and placed the required css and html files inside this folder. To use them, I added the css in the head section of the index.html file and the js in the end of the body. It works when I run the server in development mode and there are no issues. When I run it in production mode, somehow the layout gets messed up. If I refresh it with CTRL + F5 it gets fixed but when I navigate to a new page it gets ruined again and I have to CTRL + F5 it again to display properly.
This is my webpack.config.dev.js
var webpack = require('webpack');
var cssnext = require('postcss-cssnext');
var postcssFocus = require('postcss-focus');
var postcssReporter = require('postcss-reporter');
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: {
app: [
'eventsource-polyfill',
'webpack-hot-middleware/client',
'webpack/hot/only-dev-server',
'react-hot-loader/patch',
'./client/index.js',
],
vendor: [
'react',
'react-dom',
],
},
output: {
path: __dirname,
filename: 'app.js',
publicPath: 'http://0.0.0.0:8000/',
},
resolve: {
extensions: ['', '.js', '.jsx'],
modules: [
'client',
'node_modules',
],
},
module: {
loaders: [
{
test: /\.css$/,
exclude: /node_modules/,
loader: 'style-loader!css-loader?localIdentName=[name]__[local]__[hash:base64:5]&modules&importLoaders=1&sourceMap!postcss-loader',
}, {
test: /\.css$/,
include: /node_modules/,
loaders: ['style-loader', 'css-loader'],
}, {
test: /\.jsx*$/,
exclude: [/node_modules/, /.+\.config.js/],
loader: 'babel',
}, {
test: /\.(jpe?g|gif|png|svg)$/i,
loader: 'url-loader?limit=10000',
}, {
test: /\.json$/,
loader: 'json-loader',
},
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
filename: 'vendor.js',
}),
new webpack.DefinePlugin({
'process.env': {
CLIENT: JSON.stringify(true),
'NODE_ENV': JSON.stringify('development'),
}
}),
],
postcss: () => [
postcssFocus(),
cssnext({
browsers: ['last 2 versions', 'IE > 10'],
}),
postcssReporter({
clearMessages: true,
}),
],
};
This is my webpack.config.prod.js
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ManifestPlugin = require('webpack-manifest-plugin');
var ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
var cssnext = require('postcss-cssnext');
var postcssFocus = require('postcss-focus');
var postcssReporter = require('postcss-reporter');
var cssnano = require('cssnano');
module.exports = {
devtool: 'hidden-source-map',
entry: {
app: [
'./client/index.js',
],
vendor: [
'react',
'react-dom',
]
},
output: {
path: __dirname + '/dist/client/',
filename: '[name].[chunkhash].js',
publicPath: '/',
},
resolve: {
extensions: ['', '.js', '.jsx'],
modules: [
'client',
'node_modules',
],
},
module: {
loaders: [
{
test: /\.css$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?localIdentName=[hash:base64]&modules&importLoaders=1!postcss-loader'),
}, {
test: /\.css$/,
include: /node_modules/,
loaders: ['style-loader', 'css-loader'],
}, {
test: /\.jsx*$/,
exclude: /node_modules/,
loader: 'babel',
}, {
test: /\.(jpe?g|gif|png|svg)$/i,
loader: 'url-loader?limit=10000',
}, {
test: /\.json$/,
loader: 'json-loader',
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production'),
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
filename: 'vendor.js',
}),
new ExtractTextPlugin('app.[chunkhash].css', { allChunks: true }),
new ManifestPlugin({
basePath: '/',
}),
new ChunkManifestPlugin({
filename: "chunk-manifest.json",
manifestVariable: "webpackManifest",
}),
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false,
}
}),
],
postcss: () => [
postcssFocus(),
cssnext({
browsers: ['last 2 versions', 'IE > 10'],
}),
cssnano({
autoprefixer: false
}),
postcssReporter({
clearMessages: true,
}),
],
};
Package.json
{
"name": "",
"version": "2.0.0",
"description": "",
"scripts": {
"test": "cross-env NODE_ENV=test PORT=8080 MONGO_URL=mongodb://localhost:27017/mern-test node_modules/.bin/nyc node --harmony-proxies node_modules/.bin/ava",
"watch:test": "npm run test -- --watch",
"cover": "nyc npm run test",
"check-coverage": "nyc check-coverage --statements 100 --branches 100 --functions 100 --lines 100",
"start": "cross-env BABEL_DISABLE_CACHE=1 NODE_ENV=development nodemon index.js",
"start:prod": "cross-env NODE_ENV=production node index.js",
"bs": "npm run clean && npm run build && npm run build:server && npm run start:prod",
"build": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
"build:server": "cross-env NODE_ENV=production webpack --config webpack.config.server.js",
"clean": "rimraf dist",
"slate": "rimraf node_modules && npm install",
"lint": "eslint client server"
},
"pre-commit": [
"lint",
"test"
],
"repository": {
"type": "git",
"url": "git+https://github.com/Hashnode/mern-starter.git"
},
"bugs": {
"url": "https://github.com/Hashnode/mern-starter/issues"
},
"homepage": "https://github.com/Hashnode/mern-starter#readme",
"author": "Prashant Abhishek <prashant.abhishek7g#gmail.com>, Mayank Chandola <imayankchd#gmail.com>, Sandeep Panda <sandeep#hashnode.com>, Syed Fazle Rahman <fazle#hashnode.com>, Alkshendra Maurya <alkshendra#hashnode.com>",
"license": "MIT",
"dependencies": {
"babel-core": "^6.9.1",
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.15.1",
"compression": "^1.6.2",
"cross-env": "^1.0.8",
"cuid": "^1.3.8",
"express": "^4.13.4",
"intl": "^1.2.4",
"intl-locales-supported": "^1.0.0",
"isomorphic-fetch": "^2.2.1",
"jsonwebtoken": "^8.2.1",
"limax": "^1.3.0",
"mongoose": "^4.4.20",
"morgan": "^1.9.0",
"passport": "^0.4.0",
"passport-jwt": "^4.0.0",
"react": "^15.1.0",
"react-contexify": "^3.0.0",
"react-dom": "^15.1.0",
"react-helmet": "^3.1.0",
"react-intl": "^2.1.2",
"react-notify-toast": "^0.4.0",
"react-redux": "^4.4.5",
"react-router": "^2.4.1",
"react-router-dom": "^4.2.2",
"react-toastify": "^4.0.1",
"redux": "^3.5.2",
"redux-thunk": "^2.1.0",
"sanitize-html": "^1.11.4"
},
"devDependencies": {
"ava": "^0.15.2",
"babel-eslint": "^6.0.4",
"babel-loader": "^6.2.4",
"babel-plugin-webpack-loaders": "^0.7.0",
"babel-polyfill": "^6.9.1",
"babel-preset-es2015": "^6.9.0",
"babel-preset-es2015-native-modules": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-preset-react-optimize": "^1.0.1",
"babel-preset-stage-0": "^6.5.0",
"babel-register": "^6.9.0",
"chai": "^3.5.0",
"chunk-manifest-webpack-plugin": "0.1.0",
"coveralls": "^2.11.9",
"css-loader": "^0.23.1",
"css-modules-require-hook": "^4.0.1",
"cssnano": "^3.7.0",
"enzyme": "^2.3.0",
"eslint": "^2.11.1",
"eslint-config-airbnb": "^9.0.1",
"eslint-plugin-ava": "^2.4.0",
"eslint-plugin-import": "^1.8.1",
"eslint-plugin-jsx-a11y": "^1.3.0",
"eslint-plugin-react": "^5.1.1",
"eventsource-polyfill": "^0.9.6",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
"jsdom": "^9.2.1",
"json-loader": "^0.5.4",
"mock-css-modules": "^1.0.0",
"mockgoose": "^6.0.3",
"nock": "^8.0.0",
"nodemon": "^1.9.2",
"null-loader": "^0.1.1",
"nyc": "^6.4.4",
"postcss-cssnext": "^2.6.0",
"postcss-focus": "^1.0.0",
"postcss-loader": "^0.9.1",
"postcss-reporter": "^1.3.3",
"pre-commit": "^1.1.3",
"react-addons-test-utils": "^15.1.0",
"react-hot-loader": "^3.0.0-beta.2",
"redux-ava": "^2.0.0",
"redux-devtools": "^3.3.1",
"redux-devtools-dock-monitor": "^1.1.1",
"redux-devtools-log-monitor": "^1.0.11",
"rimraf": "^2.5.2",
"script-loader": "^0.7.2",
"sinon": "^1.17.4",
"style-loader": "^0.13.1",
"supertest": "^1.2.0",
"url-loader": "^0.5.7",
"webpack": "2.1.0-beta.8",
"webpack-dev-middleware": "^1.6.1",
"webpack-dev-server": "^2.1.0-beta.0",
"webpack-externals-plugin": "^1.0.0",
"webpack-hot-middleware": "^2.10.0",
"webpack-manifest-plugin": "^1.0.1"
},
"engines": {
"node": ">=4"
},
"ava": {
"files": [
"client/**/*.spec.js",
"server/**/*.spec.js"
],
"source": [
"client/**/*.js",
"server/**/*.js"
],
"failFast": true,
"babel": "inherit",
"require": [
"./server/util/setup-test-env.js"
]
},
"nyc": {
"include": [
"client/**/*.js",
"server/**/*.js"
],
"exclude": [
"**/*.spec.js",
"client/reducers.js",
"client/store.js",
"client/routes.js",
"server/util/setup-test-env.js",
"server/util/test-helpers.js",
"server/config.js",
"server/dummyData.js"
],
"reporter": [
"lcov",
"text",
"html"
]
}
}
Can this be fixed?
EDIT: It seems that the page sometimes loads correctly even without CTRL + F5 refresh. My gut tells me the issue lies with the order that the JS files are loaded. Any tips on how to keep the loading order the same in dev and prod?
In case of webpack.config.prod.js If you see this part of code
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?localIdentName=[hash:base64]&modules&importLoaders=1!postcss-loader'), 42. loader: 'style-loader!css-loader?localIdentName=[name]__[local]__[hash:base64:5]&modules&importLoaders=1&sourceMap!postcss-loader',}
Just remove ExtractTextPlugin.extract and modify this part of code to
'style-loader!css-loader?localIdentName=[name]__[local]__[hash:base64:5]&modules&importLoaders=1&sourceMap!postcss-loader'

Slow initial webpack build

I'm using React + Redux + Webpack but having an annoying development experience when every time I rerun the node server (using JetBrains WebStorm) it takes 2.5 minutes for webpack to bunde everything together.
I tried every possible technique to make webpack initial build faster but with no success. It takes 2.5 minutes to run this.
I tried:
Babel caching
Webpack module analyzer
excluding node_modules
Here is my webpack.config.js file:
let path = require('path')
let webpack = require('webpack')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
let entry = {
bundle: './src/index',
vendor: [
'react',
'react-dom',
'redux',
'react-redux',
'react-router',
'react-router-dom',
'react-router-redux',
'redux-thunk',
'd3',
'immutable',
'moment',
'axios',
'openlayers',
'react-table',
'react-select',
'reselect'
]
}
let plugins = [
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.bundle.js' }),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(ENV === 'prod' ? 'production' : 'development'),
API_URL: JSON.stringify(API_URL),
BASIC: JSON.stringify(BASIC)
}
}),
new webpack.optimize.UglifyJsPlugin({
beautify: false,
comments: false,
compress: {
sequences : true,
booleans : true,
loops : true,
unused : true,
warnings : false,
drop_console: true,
unsafe : true
}
})
]
const config = {
entry: entry,
cache: true,
devtool: 'cheap-module-source-map',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/dist/'
},
plugins: plugins,
module: {
rules: [
{
enforce: "pre",
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
},
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
query: {
plugins: ['transform-runtime']
},
include: [path.resolve(__dirname, "src")],
exclude: /node_modules/
},
{
test: /\.(css|less)$/,
use: ['style-loader', 'css-loader', 'less-loader', 'postcss-loader']
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'file-loader?hash=sha512&digest=hex&name=[hash].[ext]',
`image-webpack-loader?${JSON.stringify(query)}`
]
},
{
test: /\.(eot|woff|woff2|ttf)$/,
loader: 'url-loader?limit=30000&name=[name]-[hash].[ext]'
}
]
}
}
module.exports = config
and here is my package.json file:
{
"name": "Aloha",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"start-debug": "node $NODE_DEBUG_OPTION server.js",
"build": "webpack",
"test": "jest --verbose",
"test:watch": "npm test -- --watch",
"test-coverage": "jest --coverage",
"webpack-stats": "webpack --profile",
"startwatch": "nodemon server.js"
},
"author": "Aloha",
"license": "ISC",
"devDependencies": {
"#amcharts/amcharts3-react": "^3.0.0",
"babel-core": "^6.11.4",
"babel-eslint": "^8.0.3",
"babel-loader": "^7.1.2",
"babel-plugin-transform-runtime": "^6.9.0",
"babel-preset-react": "^6.11.1",
"babel-preset-stage-0": "^6.5.0",
"css-loader": "^0.28.4",
"eslint": "^4.12.1",
"eslint-loader": "^1.4.1",
"eslint-plugin-react": "^7.0.1",
"file-loader": "^1.1.5",
"image-webpack-loader": "^3.3.1",
"less": "^2.7.1",
"less-loader": "^4.0.5",
"postcss-loader": "^2.0.9",
"redux-mock-store": "^1.2.1",
"style-loader": "^0.19.0",
"url-loader": "^0.6.2",
"webpack-bundle-analyzer": "^2.9.1",
"webpack-dev-middleware": "^1.10.2",
"webpack-hot-middleware": "^2.12.1"
},
"dependencies": {
"axios": "^0.17.1",
"babel-preset-es2017": "^6.24.1",
"body-parser": "^1.17.2",
"classnames": "^2.2.5",
"compression": "^1.6.2",
"connect-multiparty": "^2.0.0",
"cookie-parser": "^1.4.3",
"d3": "^4.3.0",
"dotenv": "^4.0.0",
"express": "^4.15.3",
"history": "^4.7.2",
"http-proxy-middleware": "^0.17.4",
"immutable": "^3.8.1",
"lodash": "^4.17.4",
"moment": "^2.14.1",
"moment-timezone": "^0.5.13",
"nodemon": "^1.12.1",
"openlayers": "^4.5.0",
"prop-types": "^15.5.10",
"querystring": "^0.2.0",
"rc-collapse": "^1.7.5",
"react": "^16.2.0",
"react-block-ui": "^1.1.1",
"react-datetime": "^2.8.6",
"react-dom": "^16.2.0",
"react-imageloader": "^2.1.0",
"react-notification-system": "^0.2.15",
"react-redux": "^5.0.5",
"react-router-dom": "^4.2.2",
"react-router-redux": "^5.0.0-alpha.8",
"react-select": "^1.0.0-rc.5",
"react-table": "^6.7.4",
"react-tabs": "^2.1.1",
"redux": "^3.7.2",
"redux-thunk": "^2.1.0",
"request": "^2.74.0",
"reselect": "^3.0.1",
"webpack": "^3.9.1"
}
}
Help will be deeply appreciated !
This is honestly not that surprising. It depends a lot on the complexity of your code and your machine. It takes about 1 min 15 seconds for my project on a high end iMac.
Personally if you’re new to development create-react-app is still a great starting point as it has hot reloading. Use webpack watch or something similar so you can see updates as you develop.
There should be no reason to rerun the node server after changes. The only time to rerun node will be when you deploy.
You can wire in webpack dev server, and I'm quite sure a solution can be found by using concurrently
In package.json, wire in "dev":"concurrently \"npm run server\" \"npm run client\""
where "server":"nodemon index.js" and "client":"webpack-dev-server ...".
I haven't tested this exact setup, but do use it with create react app where client is simply
npm run start --prefix client
It depends a lot on your machine. Make sure you have enough disk space and good processor for your project.
Apart from this, for more improvements you can go through this link.

React.js Error: Invariant Violation: Minified React error #37

I've tried looking up in the internet, but I can't find the solution for this error.
Essentially, when I run my app in my localhost via npm start, it runs without a problem.
However, when I switch to git branch gh-pages to host in the gh-pages, I see the following error in my console.log
Uncaught Invariant Violation: Minified React error #37
_registerComponent(...): Target container is not a DOM element is what error #37 means.
Link to Git App Repository gh-pages branch
Here's my current setup:
webpack.config.js
var path = require('path');
var webpack = require('webpack');
var ghpages = require('gh-pages');
var WriteFilePlugin = require('write-file-webpack-plugin');
module.exports = {
devtool: 'source-map',
entry: [
'./src/index.js'
],
output: {
publicPath: '/',
filename: 'bundle.js',
sourceMapFilename: "./bundle.js.map",
path: path.join(__dirname, './static')
},
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},{
test: /\.s?css$/,
loaders: ['style','css','sass'],
include: path.join(__dirname, 'src')
}]
},
resolve: {
extensions: ['', '.js', '.jsx'],
alias: {
'jquery': path.join(__dirname, 'node_modules/jquery/dist/jquery'),
}
},
devServer: {
historyApiFallback: true,
contentBase: './',
outputPath: path.join(__dirname, './dist')
}
};
package.json
{
"name": "recipe-box",
"version": "1.0.0",
"description": "Portfolio",
"main": "index.js",
"repository": "",
"scripts": {
"start": "node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js",
"test": "mocha --compilers js:babel-core/register --require ./test/test_helper.js --recursive ./test",
"test:watch": "npm run test -- --watch",
"postinstall": "webpack -p"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.2.1",
"babel-loader": "^6.2.0",
"babel-preset-es2015": "^6.1.18",
"babel-preset-react": "^6.1.18",
"chai": "^3.5.0",
"chai-jquery": "^2.0.0",
"file-loader": "^0.9.0",
"gh-pages": "^0.11.0",
"image-webpack-loader": "^2.0.0",
"jquery": "^3.1.0",
"jsdom": "^9.5.0",
"mocha": "^3.0.2",
"node-sass": "^3.8.0",
"react-addons-test-utils": "^15.3.1",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.14.0",
"write-file-webpack-plugin": "^3.3.0"
},
"dependencies": {
"babel-preset-stage-1": "^6.1.18",
"css-loader": "^0.25.0",
"express": "^4.14.0",
"jquery": "^2.2.4",
"lodash": "^4.16.1",
"materialize-css": "^0.97.7",
"node-sass": "^3.8.0",
"react": "^15.3.1",
"react-bootstrap": "^0.30.3",
"react-dom": "^15.3.1 ",
"react-materialize": "^0.16.4",
"react-redux": "^4.0.0",
"react-router": "^2.0.1",
"react-tap-event-plugin": "^1.0.0",
"redux": "^3.0.4",
"redux-logger": "^2.6.1",
"sass-loader": "^4.0.0",
"shortid": "^2.2.6",
"style-loader": "^0.13.1"
}
}
Answered my own question
It looked like I had to move bundle.js out from dist folder to the same directory where my index.html was.

Webpack does not look for changes in SCSS

I'm trying to make the css and js in one big main.js but it is now listen for this changes I can't see the error, the terminal does not show error works fine for react. the webpack version that I'm using is 1.13.1. here is the list of my dependencies:
"devDependencies": {
"babel-cli": "^6.14.0",
"babel-core": "^6.14.0",
"babel-eslint": "^6.1.2",
"babel-loader": "^6.2.5",
"babel-preset-es2015": "^6.14.0",
"babel-preset-react": "^6.11.1",
"babel-preset-stage-2": "^6.13.0",
"css-loader": "^0.25.0",
"eslint": "^3.5.0",
"eslint-config-airbnb": "^11.1.0",
"eslint-loader": "^1.5.0",
"eslint-plugin-import": "^1.15.0",
"eslint-plugin-jsx-a11y": "^2.2.2",
"eslint-plugin-react": "^6.3.0",
"node-sass": "^3.10.0",
"sass-loader": "^4.0.2",
"style-loader": "^0.13.1"
}, "dependencies": {
"electron": "^1.4.1",
"electron-prebuilt": "^1.4.1",
"fs": "0.0.1-security",
"react": "^15.3.2",
"react-dom": "^15.3.2",
"react-redux": "^4.4.5",
"react-router": "^2.8.1",
"redux": "^3.6.0",
"redux-form": "^6.0.5",
"redux-promise": "^0.5.3",
"webpack": "^1.13.1"
}
and my file structure is:
src
app
components
style
app.jsx
And here is my web pack file:
const path = require("path");
const webpack = require("webpack");
module.exports = {
context: path.resolve("src/app/"),
entry: "./app.jsx",
output: {
path: path.resolve("src/"),
publicPath: "src/",
filename: "main.js"
},
devServer: {
contentBase: "./"
},
module: {
preLoaders: [
{
test: /(\.jsx$|\.js$)/,
exclude: /node_modules/,
loader: "eslint-loader"
}
],
loaders: [
{
test: /(\.jsx$|\.js$)/,
exclude: /node_modules/,
loaders: ["babel-loader"]
}, {
test: /\.scss$/,
exclude: /node_modules/,
loader: "style-loader!css-loader!sass-loader"
}
]
},
eslint: {
configFile: ".eslintrc"
},
resolve: {
extensions: [
"", ".js", ".jsx"
]
},
watch: true,
devtool: "inline-source-map"
};
I believe you have installed the necessary loaders. If not,
npm install --save-dev sass-loader css-loader style-loader
then,
loaders: [
// ...
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
}
]
then require your scss file in your js file:
require('../sass/mystyle.scss');

Categories

Resources