Wednesday, May 23, 2018

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

Leave a Comment

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?

1 Answers

Answers 1

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' 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment