Webpack ExtractTextPlugin throws error when loading Sass - sass

Trying to add sass-loader to my webpack config and running into an error:
70% 1/1 build modules/Users/a557789/Documents/f/Portal/node_modules/webpack/node_modules/webpack-core/lib/LoadersList.js:81
r.forEach(function(r) {
^
TypeError: undefined is not a function
at /Users/a557789/Documents/f/Portal/node_modules/webpack/node_modules/webpack-core/lib/LoadersList.js:81:5
at Array.reduce (native)
at LoadersList.match (/Users/a557789/Documents/f/Portal/node_modules/webpack/node_modules/webpack-core/lib/LoadersList.js:80:27)
webpack.config:
var webpack = require("webpack");
var baseDir = "dist";
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var path = require("path");
module.exports = {
context: __dirname + "/app",
entry: {
app: "./main"
},
resolve: {
extensions: ['', '.js', '.ts', '.css', '.scss']
},
output: {
path: __dirname + "/dist",
sourceMapFilename: "[name].map",
filename: "[name].js"
},
module: {
loaders: [
//https://www.npmjs.com/package/webpack-typescript
{
test: /\.ts$/,
loader: "ts-loader"
},
{
test: /\.scss$/,
loaders: ExtractTextPlugin.extract("style", "css!sass")
//loaders: ExtractTextPlugin.extract("style!css!sass")
}
],
noParse: [ /angular2\/bundles\/.+/ ]
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(true),
new ExtractTextPlugin("style.css"),
new HtmlWebpackPlugin({
template: "../index.html",
inject: "body"
})
],
devtool: "source-map"
};
I've tried a bunch of different options for the params to the extract() call but with no luck. Any help would be greatly appreciated.

Instead of using
loaders: ExtractTextPlugin.extract("style", "css!sass")
you should use
loader: ExtractTextPlugin.extract("style", "css!sass")
instead.
The error isn't particularly descriptive in this case.

In my case solution was instead ExtractTextPlugin use MiniCssExtractPlugin. More details in this video https://www.youtube.com/watch?v=JlBDfj75T3Y&list=PLblA84xge2_zwxh3XJqy6UVxS60YdusY8&index=10
So, my config looks like
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "[name].[contenthash].bundle.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
//babel
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env"],
},
},
},
//css
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "index.html",
title: "My app",
}),
new MiniCssExtractPlugin(),
new CleanWebpackPlugin(),
],
};

Related

I configured webpack for multiple pages with Bootstrap 4 and font-awesome and it's is super slow and makes my computer stuck

I have created a webpack configuration that uses bootstrap 4 and fontawesome. It has multiple entrypoints and deals with multiple html pages at the same time.
For those who are curiousI have created a repository of my workflow too:
github
It works fine and I am happy with the output. What bothers me is the speed of it. The workflow is super slow which I am unable to figure out. The CPU usage goes 100% as soon as I change some file.
Here is my webpack configuration file:
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: {
home: './src/js/home.js',
login: './src/js/login.js',
signup: './src/js/signup.js',
},
output: {
filename: 'js/[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
devServer: {
contentBase: path.join(__dirname, "dist"),
compress: true,
port: 9000
},
plugins: [
new HtmlWebpackPlugin({
filename: 'home.html',
template: 'src/home.html',
chunks: ['home'],
inject: false
}),
new HtmlWebpackPlugin({
filename: 'login.html',
template: 'src/login.html',
chunks: ['login'],
inject: false
}),
new HtmlWebpackPlugin({
filename: 'signup.html',
template: 'src/signup.html',
chunks: ['signup'],
inject: false
}),
new MiniCssExtractPlugin({
filename: "css/[name].css",
chunkFilename: "[id].css"
}),
new webpack.HotModuleReplacementPlugin(),
],
module: {
rules: [{
test: /\.(png|jp(e*)g|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 8000, // Convert images < 8kb to base64 strings
name: 'images/[hash]-[name].[ext]',
publicPath: '/'
}
}]
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"resolve-url-loader",
"sass-loader"
]
},
]
},
};

Webpack 3 loading module two times

I am using Webpack 3 as a module loader for my application. But when I analyze my vendor.js bundle, I see that d3 is loaded twice in there - once a separate module, and once as a dependency. How can I make it load only once?
I tried these, but did not work:
Adding it as alias
Adding it in the CommonsChunkPlugin
Here is my webpack config file:
var webpack = require('webpack'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
autoprefixer = require('autoprefixer'),
WebpackNotifierPlugin = require('webpack-notifier'),
ngAnnotatePlugin = require('ng-annotate-webpack-plugin'),
path = require('path'),
bourbon = require('bourbon').includePaths,
BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
var ENV = process.env.npm_lifecycle_event;
var isProd = false;
module.exports = {
cache: true,
entry: {
// vendor: [
// 'angular',
// 'jquery',
// 'velocity-animate',
// 'highcharts',
// 'd3',
// 'rickshaw',
// 'angular-block-ui',
// 'angular-sanitize',
// 'angular-animate',
// 'angular-cookies',
// './Private/Scripts/app/session/session.module',
// 'jquery.viewport',
// 'oclazyload',
// 'angular-ui-router',
// 'moment',
// 'bootstrap/js/tooltip'
// ],
wealth: './Private/Scripts/app/wealth/bootstrap.ts',
goal: './Private/Scripts/app/goal/bootstrap.ts',
login: './Private/Scripts/app/login/login.bootstrap.ts',
register: './Private/Scripts/app/register/register.bootstrap.ts',
dashboard: './Private/Scripts/app/dashboard/bootstrap.ts',
personal: './Private/Scripts/app/personal/bootstrap.ts',
resetPassword: './Private/Scripts/app/reset-password/reset-password.bootstrap.ts',
forgottenPassword: './Private/Scripts/app/forgotten-password/forgotten-password.bootstrap.ts',
products: './Private/Scripts/app/products/products.bootstrap.ts',
onboarding: './Private/Scripts/app/onboarding/onboarding.bootstrap.ts',
portfolio: './Private/Scripts/app/portfolio/bootstrap.ts',
investments: './Private/Scripts/app/investments/bootstrap.ts',
savings: './Private/Scripts/app/savings/bootstrap.ts',
customerIdentification: './Private/Scripts/app/customer-identification/customer-identification.bootstrap.ts',
wealthCoach: './Private/Scripts/app/wealth-coach/wealth-coach.bootstrap.ts',
shared: './Private/Scripts/app/shared/shared.bootstrap.ts',
riskTest: './Private/Scripts/app/risk-test/module.ts',
riskProfile: './Private/Scripts/app/risk-profile/bootstrap.ts',
upgradeProduct: './Private/Scripts/app/upgrade/upgrade.bootstrap.ts',
pendingActivation: './Private/Scripts/app/pending-activation/pending-activation.bootstrap.ts',
meeting: './Private/Scripts/app/meeting/meeting.bootstrap.ts'
},
output: {
path: __dirname + '/Private/build',
filename: 'scripts/[name].js',
publicPath: '/Private/build/'
},
devtool: 'eval',
resolve: {
extensions: ['.webpack.js', '.web.js', '.ts', '.js'],
alias: {
config: path.join(__dirname, "/Private/Scripts/app/config/", process.env.npm_lifecycle_event),
d3: path.resolve('./node_modules/d3'),
}
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: 'ts-loader'
},
{
test: /\.scss$/,
use: [
'file-loader?name=styles/[name].css',
'extract-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('autoprefixer')
];
}
}
},
// {
// loader: 'fast-sass-loader',
// }
{
loader: 'sass-loader',
options: {
sourceComments: false,
outputStyle: "compressed",
includePaths: [require('bourbon').includePaths]
}
}
]
},
{
test: /\.woff(2)?(\?[a-z0-9]+)?$/,
use: ['url-loader?name=styles/fonts/[name].[ext]']
},
{
test: /\.(ttf|eot|svg|otf)(\?[a-z0-9]+)?$/,
use: ['file-loader?name=styles/fonts/[name].[ext]']
},
{
test: /\.json$/,
use: 'json-loader'
}
]
},
node: {
fs: 'empty'
},
plugins: [
new ngAnnotatePlugin({
add: true
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'humanizeDuration': 'humanize-duration',
'moment': 'moment',
CONFIG: 'config'
}),
new WebpackNotifierPlugin({
excludeWarnings: true,
alwaysNotify: true
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.js',
minChunks(module, count) {
var context = module.context;
return context && context.indexOf('node_modules') >= 0;
},
}),
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(isProd)
}),
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /de|en/),
new webpack.optimize.ModuleConcatenationPlugin(),
new BundleAnalyzerPlugin()
]
};

Webpack img(image) path error

I'm using webpack in my project, there are two images in my project.
the first image path is: /build/img/1.png (The following is called A)
the second image path is /build/img/2.png, (The following is called B)
The two pictures have the same path. but, the A can be displayed on the page, B can not.
my webpack.config.js:
var webpack = require('webpack');
var path = require('path');
var fs = require('fs');
var AssetsPlugin = require('assets-webpack-plugin');
// var assetsPluginInstance = new AssetsPlugin();
// var proxy = require('http-proxy-middleware');
var remotePath = "./__build__/";
fs.readdir(remotePath, function (err, files) {
if (!err) {
for (var i = 0; i < files.length; i++) {
var filesName = files[i];
if (filesName.indexOf("chunk.js") > 1) {
fs.unlink('./__build__/' + filesName);
}
}
}
});
module.exports = {
entry: {
bundle: "./web_app/index.js"
},
devtool: 'cheap-module-eval-source-map',
output: {
path: __dirname + '/__build__',
filename: '[name].js',
chunkFilename: (new Date()).getTime() + '[id].chunk.js',
publicPath: '/__build__/'
},
devServer: {
hot: true,
inline: true,
proxy: {
'*': {
changeOrigin: true,
//target: 'xxx',
target: 'xxx',
secure: false
}
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
},
}),
// new webpack.HotModuleReplacementPlugin(),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./__build__/dll/lib-manifest.json')
}),
new AssetsPlugin({
filename: '__build__/webpack.assets.js',
processOutput: function (assets) {
return 'window.WEBPACK_ASSETS = ' + JSON.stringify(assets);
}
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
// new webpack.optimize.UglifyJsPlugin({
// mangle: {
// except: ['$super', '$', 'exports', 'require']
// },
// compress: {
// warnings: false,
// },
// output: {
// comments: false,
// },
// }),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
],
resolve: {
extensions: ['', '.js', '.jsx'],
resolve: {
alias: {
moment: "moment/min/moment-with-locales.min.js"
}
}
},
module: {
loaders: [
{
test: /\.jsx?$/,
// loaders: ['babel-loader?presets[]=es2015&presets[]=react&presets[]=stage-0'],
loader: 'babel-loader',
query: {
plugins: ["transform-object-assign", "add-module-exports"],
presets: ['es2015', 'stage-0', 'react']
},
include: path.join(__dirname, '.')
}, {
test: /\.css$/,
loader: 'style!css'
}, {
test: /\.less$/,
loader: 'style!css!less'
}, {
test: /\.(eot|woff|svg|ttf|woff2|gif|appcache)(\?|$)/,
exclude: /^node_modules$/,
loader: 'file-loader?name=[name].[ext]'
}, {
test: /\.(png|jpg)$/,
exclude: /^node_modules$/,
loader: 'url?name=[name].[ext]'
}
]
}
};
my project structure
Image sequence: React code, project directory, dev Tool
I've merged several images, because stackoverflow rules that I can only publish two links

Prestashop 1.7 webpack very slow

Here is my stats file for analyse.
I use latest version of prestashop (1.7), i want to use build in webpack script placed on _dev, the problem is a very slow compilating and watch tasks.
I run webpack by:
npm run watch
Result:
Version: webpack 1.14.0
Time: 12092ms
How i can improve performance?
I found same problem my webpack.config file is
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var plugins = [];
var production = false;
if (production) {
plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
);
}
plugins.push(
new ExtractTextPlugin(
path.join(
'..', 'css', 'theme.css'
)
)
);
module.exports = {
entry: [
'./js/theme.js'
],
output: {
path: '../assets/js',
filename: 'theme.js'
},
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loaders: ['babel-loader']
}, {
test: /\.scss$/,
loader: ExtractTextPlugin.extract(
"style",
"css?sourceMap!postcss!sass?sourceMap"
)
}, {
test: /.(png|woff(2)?|eot|ttf|svg)(\?[a-z0-9=\.]+)?$/,
loader: 'file-loader?name=../css/[hash].[ext]'
}, {
test: /\.css$/,
loader: "style-loader!css-loader!postcss-loader"
}]
},
postcss: function() {
return [require('postcss-flexibility')];
},
externals: {
prestashop: 'prestashop'
},
devtool: 'source-map',
plugins: plugins,
resolve: {
extensions: ['', '.js', '.scss']
}
};

webpack, sass, react-css-modules - ReferenceError window is not defined

I'm using webpack and React with react-css-modules and scss files. When i try and build it gives me an error on every file that imports scss files -
ERROR in ./app/components/Buttons/Button.scss
Module build failed: ReferenceError: window is not defined
I have googled for a solid day and a half and have got no where! Please help!
Here's my webpack set up:
var webpack = require('webpack');
var PROD = (process.env.NODE_ENV === 'production');
var precss = require('precss');
var autoprefixer = require('autoprefixer');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: [
'./app/index.jsx'
],
output: {
path: __dirname + '/dist',
filename: PROD ? 'bundle.min.js' : 'bundle.js'
},
watchOptions: {
poll: true
},
module: {
preLoaders: [
{
test: /\.jsx$|\.js$/,
loader: 'eslint-loader',
include: __dirname + '/assets',
exclude: /bundle\.js$/
}
],
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ['es2015', 'react']
}
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', ['style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded'])
}
]
},
postcss: [autoprefixer({ browsers: ['last 2 versions'] })],
resolve: {
extensions: ['', '.js', '.jsx']
},
plugins: PROD ? [
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false }
})
] : [
HTMLWebpackPluginConfig,
new ExtractTextPlugin("styles.css", {
allChunks: true
})
]
};
Thanks in advance!
This question keeps popping up when I tried to resolve the same error for Webpack 2, scss, extracttextplugin, and react. The following worked for me.
{
test:/\.scss$/,
use:ExtractTextPlugin.extract({fallback:"style-loader",use:["css-loader","sass-loader"]}),
include:path.join(__dirname,"client/src"),
},
Hope this helps.
I think you have to change it to this, the second parameter goes as a string instead of array. Also removed the repeated use of the style loader.
loader: ExtractTextPlugin.extract('style', 'css?sourceMap&localIdentName=[local]___[hash:base64:5]!resolve-url!sass?outputStyle=expanded')

Resources