Situation
I have a webpack setup, where I have a rule that extracts CSS and/or SASS from .ts files using the extract-text-webpack-plugin and sass-loader.
I import my SCSS file in a seperate .ts file
import './scss/style.scss'
Problem
A CSS file is expected to be in the output folder ( dist ).
The compilation completes without an error, yet there is no CSS file in the build folder.
Here is my webpack configuration:
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var styleString = require('css-to-string-loader');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractSass = new ExtractTextPlugin({
filename: "[name].css",
disable: process.env.NODE_ENV === "development"
});
var helpers = require('./helpers');
var isProd = process.env.NODE_ENV === 'production';
module.exports = {
entry: {
polyfills: './src/polyfills.ts',
vendor: './src/vendor.ts',
app: isProd ? './src/main.aot.ts' : './src/main.ts'
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [{
test: /\.ts$/,
loaders: [
'babel-loader',
{
loader: 'awesome-typescript-loader',
options: {
configFileName: isProd ?
helpers.root('tsconfig-aot.json') :
helpers.root('tsconfig.json')
}
},
'angular2-template-loader'
],
exclude: [/node_modules/]
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015']
}
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[ext]'
},
{
test: /\.(json)$/,
loader: 'file-loader?name=assets/mocks/[name].[ext]'
},
{
test: /\.(css|scss)$/,
loaders: ['to-string-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)#angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
};
Reason
The reason there is not output CSS file is because you are not using the
const extractSass = new ExtractTextPlugin({
filename: "[name].css",
disable: process.env.NODE_ENV === "development"
});
in your CSS|SCSS rule
{
test: /\.(css|scss)$/,
loaders: ['to-string-loader', 'css-loader', 'sass-loader']
}
Solution
You have to make use of the use property like so:
{
test: /\.(css|scss)$/,
use: extractSass.extract({ // <==== Right here, note the "extractSass"
use: [
{ loader: "to-string-loader" },
{ loader: "css-loader" },
{ loader: "sass-loader" }
],
fallback: "style-loader"
})
}
And add to your plugins array the ExtractTextPlugin instance ( extractSass ):
plugins: [
extractSass
]
You might also want to take a look here.
Related
all my images seem to be 404, I think I have the right path as I just stuck them in the root directory
I am using file loader and trying to load svg files
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require('webpack');
module.exports = {
entry: ["babel-polyfill", "./src/index.js"],
output: {
// filename and path are required
filename: "main.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
// JSX and JS are all .js
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
}
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
template: "./src/index.html"
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
]
};
here is an example I setup: https://github.com/chobo2/webpack-serve-example
You have to import:
import image from './Freesample.svg'
And use it like;
<img src={image}/>
But you also need an appropriate loader for it, another rule:
module.exports = {
entry: ["babel-polyfill", "./src/index.js"],
output: {
// filename and path are required
filename: "main.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
// JSX and JS are all .js
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
}
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
},
{
test: /\.(png|jpg|jpeg|gif)$/,
loader: 'file-loader'
}
]
},
plugins: [
new CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
template: "./src/index.html"
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
]
};
You need to use import.
import image from './Freesample.svg'
And use it like;
<img src={image}/>
I'm using "webpack": "^3.1.0" and "extract-text-webpack-plugin": "^1.0.1"
Trying to compile sass and I get the following error: Error: "extract-text-webpack-plugin" loader is used without the corresponding plugin, refer to https://github.com/webpack/extract-text-webpack-plugin for the usage example
I have used this as per the documents provided - don't understand why I'm getting webpack build errors.
Here is my webpack file:
const debug = process.env.NODE_ENV !== "production";
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
context: path.join(__dirname, "src"),
devtool: debug ? "inline-sourcemap" : null,
entry: ['./js/client.js', './styles/base.scss'],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'],
}
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
//resolve-url-loader may be chained before sass-loader if necessary
use: ['css-loader', 'sass-loader']
})
}
]
},
output: {
path: __dirname + "/src/",
filename: "client.min.js"
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
new ExtractTextPlugin('main.css')
],
};
You need to include something to tell where webpack to look, for example:
{
test: /(\.css|\.scss|\.sass)$/,
include: path.join(__dirname, "../src"), // Include or exclude node modules
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader", "sass-loader"],
}),
},
Here is my webpack.config.babel.js file I hope this will helps you.
import HtmlWebpackPlugin from 'html-webpack-plugin';
import ExtractTextPlugin,{extract} from 'extract-text-webpack-plugin';
import {resolve,join} from 'path';
// import webpack from 'webpack';
// var isProd = process.env.NODE_ENV === 'production'; //return true or false
// var cssDev = [ "style-loader", "css-loader", "sass-loader" ];
// var cssProd = extract({
// fallback: "style-loader",
// use: [ "css-loader", "sass-loader"],
// publicPath:'/dist'
// });
// var cssConf = isProd ? cssProd : cssDev;
module.exports = {
entry: {
app:'./src/app.js',
},
output: {
path: join(__dirname, "dist"),
filename : '[name].bundle.js'
},
module: {
rules:[
{
test: /\.scss$/,
exclude: /node_modules/,
use: extract({
fallback: "style-loader",
use: [ "css-loader", "sass-loader"],
publicPath:'/dist'
})
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.(png|jpg|gif)$/,
use:"file-loader",
}
]
},
devServer:{
contentBase: join(__dirname, "dist"),
compress: true,
port: 9000,
stats:'errors-only',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack starter project',
template: './src/index.html',
hash:true,
excludeChunks: ['contact'],
minify:{
collapseWhitespace: true,
minifyCSS: true,
minifyJS:true,
}
}),
new ExtractTextPlugin({
filename: "app.css",
// disable: !isProd,
disable: false,
allChunks: true
}),
// new webpack.HotModuleReplacementPlugin(),
// new webpack.NamedModulesPlugin(),
]
}
you have to change the version of Extract Text Plugin
Instead of new ExtractTextPlugin('main.css') use new
ExtractTextPlugin({ filename: "main.css"})
I have the following webpack file, however, when I run npm run dev the name.bundle.css file doesn't get generated: (no errors either)
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
context: path.resolve(__dirname, './resources/'),
entry: {
app: './index.jsx'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, './public/assets/'),
publicPath: '/assets/'
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: [{
loader: 'css-loader'
}],
}),
},
{
test: /\.jsx|js$/,
exclude: [/node-modules/],
use: [
{
loader: "babel-loader",
options: { presets: ['react', 'es2015', 'stage-1'] }
}
]
},
{
test: /\.(sass|scss)$/,
use: ["style-loader", "css-loader", "sass-loader"]
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: ['file-loader?name=[name].[ext]']
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'file-loader?name=public/fonts/[name].[ext]'
}
]
},
resolve: {
modules: [
path.resolve(__dirname, './resources/'),
'node_modules'
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'common'
}),
new ExtractTextPlugin({
filename: '[name].bundle.css'
})
]
}
my CSS folder is:
CSS
- app.scss
COMPONENTS
comp1.scss
comp2.scss
it works this way "import styles from './css/app.scss';" but I would expect this to generate a app.bundle.css:
new ExtractTextPlugin({
filename: '[name].bundle.css'
})
You have 2 rules for both css and sass.
I think in your case you only need one:
test: /\.(sass|scss)$/,
use: ExtractTextPlugin.extract({
use: [{
loader: "css-loader"
}, {
loader: "sass-loader"
}],
fallback: "style-loader"
})
and like you said, you should import the scss files in the js files import './css/app.scss'
I want extract and compile css code from sass file with extract-text-webpack-plugin , but webpack give me this Error :
ERROR in ./style.scss
Module parse failed: H:\projects\new\app\style.scss Unexpected token (1:4)
You may need an appropriate loader to handle this file type.
| body{
| background-color: #d9534f;
| }
# ./index.js 2:0-22
my version of webpack and extract-text-webpack-plugin :
"extract-text-webpack-plugin": "^2.0.0-beta.4",
"webpack": "^2.1.0-beta.22"
my webpack.config.js
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let extractCSS = new ExtractTextPlugin('test.css');
module.exports = {
context:path.resolve(__dirname, 'app'),
entry: './index.js',
output: {
path: path.resolve(__dirname, 'app'),
filename: 'bundle.js'
},
module: {
loader: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}
, {
test: /\.s?css$/,
loader: extractCSS.extract({ fallbackLoader: 'style-loader', loader: 'css-loader!sass-loader' })
}
, {
test: /\.html$/,
loader: 'raw-loader'
},
{
test: /\.(jpe?g|png|gif)$/,
exclude: /(node_modules)/,
loader: 'url-loader?limit=10000'
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&minetype=application/font-woff'
}, {
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader'
}
]
},
plugins: [
extractCSS,
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'app')+'/index.html',
inject: 'body'
})
]
};
and my simple .scss file :
body{
background-color: #d9534f;
}
Works for me this way.
Add const ExtractTextPlugin = require("extract-text-webpack-plugin"); in the top.
and add this to loaders:
test: /\.s?css$/,
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!sass-loader'}),
},
I Solve it :
module: {
loaders: [
{
instead of
module: {
loader: [
{
here you go buddy
{ test: /\.sass$/, use: extractText.extract({ fallback: 'style-loader', use: 'css-loader!sass-loader' }) }
I'm trying to load the perfect-tooltip jquery plugin (http://tborychowski.github.io/perfecttooltip/) using webpack.
I successfully loaded other jquery plugins like: typed.js and backstretch by following the instructions provided here (Managing jQuery plugin dependency in webpack) but they don't seem to work with that specific plugin.
When I run the bundle an error tells me that the tooltip function (exported by the plugin) is not defined. It seems the plugin is not loaded by jquery. I thought the plugin tried to load its own instance of jquery so I used an alias:
alias: {
'jquery': require('jquery'),
}
It didn't solve the problem.
My current webpack configuration:
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var moment = require('moment');
var path = require('path');
var environment = process.env.APP_ENVIRONMENT || 'dev';
module.exports = {
entry: {
'app': './src/main.ts',
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts'
},
devtool: 'source-map',
output: {
path: './dist',
filename: '[name].browser.' + moment().format('DDMMYYYYHHmm') + '.js'
},
module: {
loaders: [
{ test: /\.component.ts$/, loader: 'ts!angular2-template' },
{ test: /\.ts$/, exclude: /\.component.ts$/, loader: 'ts' },
{ test: /\.html$/, loader: 'raw-loader' },
{ test: /\.css$/, include: path.resolve('src/app'), loader: 'raw-loader' },
{
test: /\.css$/, exclude: path.resolve('src/app'), loader: ExtractTextPlugin.extract('style', 'css', {
fallbackLoader: "style-loader",
loader: "css-loader"
})
},
{ test: /\.(png|jpe?g|gif|ico)$/, loader: 'file?name=fonts/[name].[ext]' },
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff&name=fonts/[name].[ext]" },
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff&name=fonts/[name].[ext]" },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream&name=fonts/[name].[ext]" },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file?name=fonts/[name].[ext]" },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml&name=fonts/[name].[ext]" },
]
},
resolve: {
extensions: ['', '.js', '.ts', '.html', '.css']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new webpack.DefinePlugin({
app: {
environment: JSON.stringify(environment),
config: JSON.stringify(require('./profile/' + environment + ".profile.js"))
}
}),
new CleanWebpackPlugin(
['dist']
),
new CopyWebpackPlugin([
{ from: './src/images', to: 'images' }
]),
new ExtractTextPlugin('[name].browser.css'),
new webpack.optimize.UglifyJsPlugin({ minimize: true }),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
]
};
Any insight?
Eventually I managed to load that script.
The package.json file provided in the package doesn't have a main property, Webpack was simply trying to bundle all files in the package.
I solved that by requiring two specific files: "js/jquery.tooltip.js" and "css/tooltip.css".