I have an issue with css order that compiles with webpack.
I currently use these packages in dependencies:
"css-loader": "^0.28.4",
"style-loader": "^0.18.2",
"sass-loader": "^6.0.6",
"sass-resources-loader": "^1.3.0",
"webpack": "^3.5.5",
Here is my webpack.config.js
const { alias } = require('./webpack/common.js');
const path = require('path');
const webpack = require('webpack');
const Dashboard = require('webpack-dashboard');
const DashboardPlugin = require('webpack-dashboard/plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const nodeEnv = process.env.NODE_ENV || 'development';
const isProd = nodeEnv === 'production';
const sourcePath = path.join(__dirname, './src');
const staticPath = path.join(__dirname, './dist');
const commonCssOptions = {
sass: {
loaders: ['sass-loader', 'sass-resources-loader'],
},
context: path.resolve(__dirname, '.'),
output: {
path: 'dist',
},
};
const plugins = [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
filename: 'vendor.bundle.js',
}),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify(nodeEnv) },
}),
new webpack.NamedModulesPlugin(),
new ExtractTextPlugin({ filename: 'css/bundle.css', disable: false, allChunks: true }),
new webpack.ContextReplacementPlugin(
/moment[/\\]locale/,
/(en-gb)\.js/
),
];
if (isProd) {
plugins.push(
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false,
options: commonCssOptions,
})
);
} else {
const dashboard = new Dashboard();
plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.LoaderOptionsPlugin({
options: commonCssOptions,
}),
new DashboardPlugin(dashboard.setData)
);
}
module.exports = {
devtool: isProd ? false : 'cheap-module-source-map',
entry: {
js: './src/index.js',
vendor: [
'babel-polyfill',
'bootstrap-loader',
'classnames',
'react',
'react-dom',
'react-redux',
'redux',
'react-router',
'react-router-dom',
// 'moment',
],
},
output: {
path: staticPath,
publicPath: '/',
filename: '[name].bundle.js',
},
module: {
rules: [
{
test: /\.html$/,
exclude: /node_modules/,
use: {
loader: 'file-loader',
query: {
name: '[name].[ext]',
},
},
},
{
test: /\.s?css$/,
exclude: /node_modules/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
modules: true,
localIdentName: '[name]__[local]_[hash:base64:5]',
},
},
{
loader: 'sass-loader',
options: {
includePaths: [
path.join(__dirname, './components-lib/src/assets/styles'),
],
},
},
{
loader: 'sass-resources-loader',
options: {
resources: [
'./components-lib/src/assets/styles/_variables.scss',
'./components-lib/src/assets/styles/_mixins.scss',
],
},
},
'postcss-loader',
],
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [
'babel-loader',
],
},
{
test: /\.(woff|woff2|eot|ttf|svg)(\?.*$|$)/,
loader: 'file-loader',
query: {
name: '[name].[ext]',
},
},
],
},
resolve: {
extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.jsx', '.js'],
modules: [
'node_modules',
sourcePath,
],
alias,
},
plugins,
devServer: {
contentBase: './src',
historyApiFallback: true,
host: '0.0.0.0',
port: 3000,
compress: isProd,
inline: !isProd,
hot: !isProd,
quiet: true,
stats: {
assets: true,
children: false,
chunks: false,
hash: false,
modules: false,
publicPath: false,
timings: true,
version: false,
warnings: false,
colors: {
green: '\u001b[32m',
},
performance: {
hints: false,
},
},
},
externals: {
cheerio: 'window',
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true,
},
};
On initial load I have wrong css order
But on hot reload the order becomes correct
My component library is a git submodule (if it is important)
I've noticed that including HotModuleReplacementPlugin will change CSS order on occasion, still trying to figure out why.
I think because of the way things get re-written, the ordering is bound to change i.e. the new stuff will be at the bottom. I've also noticed Webpack not being able to guarantee the order of css. I wasn't able to find a 'webpack' solution and i'm not sure if there is one. Probably bot what you wanted to hear, sorry!
The only way i've solved it was by either using smaccs/BEM notation and/or ensuring writing css rarely/never over-writes other css. For example, if you need to use a 'modifier' to change a background from white to red, then that is actually two modifiers and the default 'base' class doesn't have a background set at all. This way you can guarantee ordering doesn't matter. TBH, this turned out to be a more readable and maintainable way of writing css, but i digress!
Related
to compile my .scss files I use webpack.
What i want to achieve is to get for example
styles.b0eda78ad870282c8cb9fd58884415d7.css
instead of
styles.css
When I add to webpack option [hash] (now commented in source) - then every change in .scss files generate new .css files. For example 3 changes in .scss will generate 3 new files with different hashes:
themeA.b0eda78ad870282c8cb9fd58884415d7.css
themeA.2c0521243fe51696a6d08ae5443a6721.css
themeA.6ebd2d65f4d311fbac8441141826a9a8.css
I want only to update one css file with new hash and do not create new files.
My webpack configuration
const themeA = `${mainDirectory}/commons/themeA.scss`;
const themeB = `${mainDirectory}/commons/scss/shop/themeB.scss`;
const themeC = `${mainDirectory}/commons/themeC.scss`;
const themeD = `${mainDirectory}/commons/scss/shop/themeD.scss`;
let sassFiles;
const themeMap = new Map([
['a', themeA],
['b', themeB],
['c', themeC],
['d', themeD],
]);
if (theme === undefined) {
sassFiles = [...themeMap.values()];
} else {
sassFiles = [
`${mainDirectory}/commons/${theme}.scss`,
`${mainDirectory}/commons/scss/shop/${theme}_shop.scss`,
];
}
module.exports = {
entry: [...sassFiles],
mode: 'development',
output: {
path: path.resolve(mainDirectory, 'commons'),
filename: 'hot/sassBundle.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.scss$/,
sideEffects: true,
use: [
{
loader: 'file-loader',
options: {
minimize: true,
name: '[name].css',
// hashed css
// name: '[name].[hash].css',
outputPath: '/css',
},
},
{
loader: 'extract-loader',
},
{
loader: 'css-loader',
options: {
url: false,
sourceMap: !buildMode,
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: !buildMode,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: !buildMode,
convertToAbsoluteUrls: false,
},
},
],
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
},
{
test: /\.(woff|woff2|eot|ttf)$/,
loader: 'url-loader?limit=100000',
},
],
},
plugins: [
new webpack.SourceMapDevToolPlugin({}),
new ReplaceInFileWebpackPlugin([
{
dir: `${mainDirectory}/commons/css/`,
test: [/\.css$/],
rules: [
{
search: /\/\*# sourceURL.+\\*/g,
replace: '',
},
],
},
]),
],
};
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 made a previous post vaguely describing my issues, and unfortunately it got disregarded. My issue is that I'm trying to inline my CSS into my HTML when it is rendered on the server-side. All of the tutorials only show solutions to make external files. I want the traditional 'style-loader' inline behavior. I'm using Webpack, React, NodeJS, & Babel.
Webpack Config:
const ExtractTextPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const devMode = process.env.NODE_ENV !== 'production';
module.exports = {
entry: './src/js/app.js',
output: {
path: __dirname + "/src/js/",
filename: 'app.bundle.js'
},
mode: 'development',
plugins: [
new ExtractTextPlugin({
filename: devMode ? '[name].css' : '[name].[hash].css',
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
})
],
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
extractComments: true
}),
new OptimizeCssAssetsPlugin({}),
new CompressionPlugin()
]
},
module: {
rules: [
{
test: /\.(jsx|js)?$/,
exclude: /(node_modules)/,
use: [{
loader: "babel-loader",
options: {
cacheDirectory: true,
presets: ['react', 'es2015']
}
}]
},
{
test: /\.(sc|c)ss$/,
use: [
devMode ? 'style-loader' : ExtractTextPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: 'ko_[sha1:hash:hex:3]'
}
},
'sass-loader'
],
}
]
},
};
.babelrc
{
"presets": [
"es2015",
"react"
],
"plugins": [
[
"css-modules-transform",
{
"generateScopedName": "ko_[sha1:hash:hex:3]",
"extensions": [
".scss"
]
}
]
]
}
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
I'm set postcss-loader + style-loader on webpack, and I'am using webpack-dev-server, but every time that change css, the webpack don't rebuild.
script webpack dev server I use on scripts npm:
webpack-dev-server --hot
webpack.config.js
const path = require('path')
const webpack = require('webpack')
const lost = require('lost')
const mqpacker = require('css-mqpacker')
const precss = require('precss')
const cssnano = require('cssnano')
const nested = require('postcss-nested')
const cssnext = require('postcss-cssnext')
const atImport = require('postcss-import')
const postCSSFocus = require('postcss-focus')
const pxtorem = require('postcss-pxtorem')
const flexBugsFixes = require('postcss-flexbugs-fixes')
const rucksack = require('rucksack-css')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const objectFit = require('postcss-object-fit-images')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const StatsPlugin = require('stats-webpack-plugin')
const environment = process.env.NODE_ENV
module.exports = {
devServer: {
colors: true,
historyApiFallback: true,
inline: false,
port: 8080,
},
entry: [
'webpack/hot/dev-server?reload=true',
path.join(__dirname, 'src/script/app.js')
],
output: {
path: path.join(__dirname, '/build/'),
filename: 'index.js',
publicPath: '/'
},
resolve: {
extensions: ['', '.js', '.css', '.json']
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html',
inject: 'body',
filename: 'index.html'
}),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new ExtractTextPlugin('[name].min.css'),
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false,
screw_ie8: true
}
}),
new StatsPlugin('webpack.stats.json', {
source: false,
modules: false
}),
new CopyWebpackPlugin([{
context: 'src/svg',
from: '*.svg',
to: 'svg'
}])
],
module: {
loaders: [{
test: /\.worker\.js$/,
loader: 'babel!worker?inline!'
}, {
test: /\.js?$/,
exclude: [/node_modules/, /\.worker\.js$/],
loader: 'babel'
}, {
test: /\.mod\.css$/,
loader: ExtractTextPlugin.extract('style', 'css?modules!postcss')
}, {
test: /\.css$/,
exclude: /\.mod\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader')
}, {
test: /\.(png|jpe?g|svg|gif)$/,
loaders: [
'file?hash=sha512&digest=hex&name=[hash].[ext]',
'image-webpack?{progressive:true, optimizationLevel: 7, interlaced: false, pngquant:{quality: "65-90", speed: 4}}'
]
}, {
test: /\.svg$/,
loader: 'url?limit=65000&mimetype=image/svg+xml&name=fonts/[name].[ext]'
}, {
test: /\.woff$/,
loader: 'url?limit=65000&mimetype=application/font-woff&name=fonts/[name].[ext]'
}, {
test: /\.woff2$/,
loader: 'url?limit=65000&mimetype=application/font-woff2&name=fonts/[name].[ext]'
}, {
test: /\.[ot]tf$/,
loader: 'url?limit=65000&mimetype=application/octet-stream&name=fonts/[name].[ext]'
}, {
test: /\.eot$/,
loader: 'url?limit=65000&mimetype=application/vnd.ms-fontobject&name=fonts/[name].[ext]'
}],
resolve: {
extensions: ['', '.js', '.css', '.json']
}
},
postcss: compiler => [
atImport({
addDependencyTo: compiler
}),
precss,
cssnext({
browsers: ['last 2 versions']
}),
pxtorem({
propWhiteList: ['font', 'font-size', 'line-height', 'letter-spacing'],
selectorBlackList: []
}),
lost,
postCSSFocus,
flexBugsFixes,
rucksack,
objectFit,
nested,
mqpacker,
cssnano({
autoprefixer: false
})
]
}
Lack configure something? Because in Webpack documentation, can not find anything about
Did you require the css file in your main javascript file? For example, in your index.jsx:
require("somestyle.css");
css-loader will only know about the CSS files that the application has required. For more information, see: https://github.com/webpack/css-loader