extract-text-webpack-plugin to output css from scss in new folder in output - css

I can't seem to make extract-text-webpack-plugin generate the css from scss in a special folder in output. I know that there is a publicPath option but it doesn't seem to do anything. The css is still generated along with the other css's in my output folder.
can anyone help?
in my config:
test: /(add-to-home\.scss)$/,
loader: ExtractTextPlugin.extract("style","css!postcss!sass", {publicPath: "output/a/b"})
thanks

To output the your style.css file in "output/a/b"
You need to use the ExtractTextPlugin
{
test: /(\.scss|\.css)$/,
loader: ExtractTextPlugin.extract('style', 'css?postcss!sass'),
}
In the plugin section use :
plugins: [
new ExtractTextPlugin('output/a/b/style.css', {allChunks: true})
],
This will output the extracted css in the output/a/b/ folder.

Related

ExtractTextWebpackPlugin always outputs file, even if there are no changes

I have a project that bundles the client-side files using Webpack. We are bundling the CSS using the ExtractTextWebpackPlugin. The problem is when I edit a javascript file the CSS bundle always gets re-built despite there being absolutely no changes to the CSS state.
How can I bundle CSS but only when there are changes to the CSS files?
Extracted from my webpack config:
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: 'css-loader'
})
},
...
plugins: [
new ExtractTextPlugin(isDebug ? '[name].css' : '[name].[chunkhash].css')
],
whenever ExtractTextPlugin sees a import statement with css extension it will automatically extract the text contant of that css file whethere it changes or not
if you are using it to debug then use style-loader and HMR(Hot Module Replacement) for better experence something like this
isDebug
? {
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
: {
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: "css-loader"
})
}
if you want to use current configration and don't want ExtractTextPlugin to build css file and you are importing them in your javascript file using import then somehow you have to remove import statement for css files when there is no change in that css file
and if you are adding css file in your webpack config entry section then it would be easy because webpack allow custom command argument and you can do this by exporting a function in your webpack config file insted of object
//webpack.config.js
module.exports = function(env) {
return {
entry: {
main: env.includeCss
?
["./src/index.js", "./src/main.css"] //build with css
: ["./src/index.js"] //build without css
},
.
.
.
.
}
}
you can pass env.includeCss by command argument like this
webpack --config ./webpack.config.prod.js --env.includeCss
//notice --env.includeCss witch will set env.includeCss as true
run with --env.includeCss normally and without --env.includeCss when you dont want to compile css file
Not directly related to your question but I noticed you use [chunkhash] for extracted CSS. This will make your css name change even if you haven't change content in you CSS files.
Use [contenthash] instead.
https://survivejs.com/webpack/optimizing/adding-hashes-to-filenames/#setting-up-hashing
If you are using ExtractTextPlugin, you should use [contenthash]. This way the generated assets get invalidated only if their content changes.

How to use absolute paths within a css-module to compose other classes instead of relative paths

I want to be able to have a folder in the root of my app "src" that contains reusable css which I can compose from in the css modules wi
In my css no my class has composes: table from './../../../css-vars/index.css'; but i am trying to just be able to use composes: table from 'css-vars/index.css'; and have it resolve to the root of my project. Currently when I try this i get this error:
Module not found: 'css-vars/index.css' in /Users/jfarina/Desktop/schedule-react/src/components/layout
Here is what my css loader looks like:
{
test: /\.css$/,
loaders: [
'style?sourceMap',
'css-loader?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
'postcss-loader'
]
},
Any idea?
I solved a similar problem with with postcss smart-import by adding a path with my source. Is there a similar solution with the css-loader? I noticed there is a root query param ter but adding that didn't help
smartImport({
addDependencyTo: webpack,
path: [ path.resolve(__dirname, 'src') ]
})
You can try postcss-modules-resolve-imports

Minify and add hash to css files webpack

I am using webpack for my Angular 2 project.
Inside the src folder I have a global css folder and component and other folders.
My webpack.config.js is outside the src folder.
I am using CopyWebpackPlugin to copy the css folder to the dist folder :
new CopyWebpackPlugin([
{ from: 'src/css', to: 'css'}
]),
I am using the following loader also for css :
exports.css = {
test: /\.css$/,
loader: 'to-string!css?-minimize!postcss',
};
But the deal is that I want to add a hash to each css file name and also then change the css file name in the index.html since these are global files included in the index.html. What is the best way to achieve this?
EDIT : While changing the code i realised that the loader property only applies to the css inside the components folder and not to the outside folder. why is this?
Use https://github.com/webpack/extract-text-webpack-plugin.
example in webpack.config.js
config.plugins.push(
new ExtractTextPlugin({filename: 'css/[name].[hash].css'})
);
...
config.module = {
rules: [
{
test: /\.css$/,
exclude: root('src', 'app'),
loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: ['css', 'postcss']})
}
]
}
Do not use CopyWebpackPlugin for application sources. This will bypass Webpack's loaders and lock you out of all of Webpack's features.
Simply use ES6 imports, require, require.ensure or System.import to require your stylesheets. Alterantively, as MichaƂ suggested, use ExtractTextPlugin in production when applicable.

Webpack ExtractTextPlugin without babel

I'm trying to get webpack to bundle all my stylesheets but I'm at a loss.
I don't want to use babel, so I try to do this in my main.js file:
require('./styles/core.css');
When I run webpack i get the following error:
You may need an appropriate loader to handle this file type.
My loader is:
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('css!scss'),
include: __dirname + '/app/styles'
}
]
Any ideas?
You have loader only for .scss and you are trying to use it on .css file. Change test in loader to:
test: /\.(css|scss)$/,

With Webpack, is it possible to generate CSS only, excluding the output.js?

I'm using Webpack with the extract-text-webpack-plugin.
In my project, I have some build scripts. One of the build scripts is supposed to bundle and minify CSS only. As I'm using Webpack for the other scripts, I found it a good idea to use Webpack even when I only want to bundle and minify CSS.
It's working fine, except that I can't get rid of the output.js file. I don't want the resulting webpack output file. I just want the CSS for this particular script.
Is there a way to get rid of the resulting JS? If not, do you suggest any other tool specific for handling CSS? Thanks.
There is an easy way, no extra tool is required.
There is an easy way and you don't need extra libraries except which you are already using: webpack with the extract-text-webpack-plugin.
In short:
Make the output js and css file have identical name, then the css file will override js file.
A real example (webpack 2.x):
import path from 'path'
import ExtractTextPlugin from 'extract-text-webpack-plugin'
const config = {
target: 'web',
entry: {
'one': './src/one.css',
'two': './src/two.css'
},
output: {
path: path.join(__dirname, './dist/'),
filename: '[name].css' // output js file name is identical to css file name
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
},
plugins: [
new ExtractTextPlugin('[name].css') // css file will override generated js file
]
}
Unfortunately, that is currently not possible by design. webpack started as a JavaScript bundler which is capable of handling other "web modules", such as CSS and HTML. JavaScript is chosen as base language, because it can host all the other languages simply as strings. The extract-text-webpack-plugin is just extracting these strings as standalone file (thus the name).
You're probably better off with PostCSS which provides various plugins to post-process CSS effectively.
One solution is to execute webpack with the Node API and control the output with the memory-fs option. Just tell it to ignore the resulting js-file. Set the output.path to "/" in webpackConfig.
var compiler = webpack(webpackConfig);
var mfs = new MemoryFS();
compiler.outputFileSystem = mfs;
compiler.run(function(err, stats) {
if(stats.hasErrors()) { throw(stats.toString()); }
mfs.readdirSync("/").forEach(function (f) {
if(f === ("app.js")) { return; } // ignore js-file
fs.writeFileSync(destination + f, mfs.readFileSync("/" + f));
})
});
You can clean up your dist folder for any unwanted assets after the done is triggered. This can be easily achieved with the event-hooks-webpack-plugin
//
plugins: [
new EventHooksPlugin({
'done': () => {
// delete unwanted assets
}
})
]
Good Luck...

Resources