-
Notifications
You must be signed in to change notification settings - Fork 125
SASS loader support #14
Comments
😁 I'm glad to hear that! Unfortunately, the I did start an effort to fully support the loader APIs but it got really ugly and I'm not sure if it's worth the trouble (or if it will end up being an improvement in the first place, so much data to transfer between the processes and not all of it is serializable.) I am ready to take another fresh look at solving this though, so I'll be notifying you if something works out. |
I might be willing to invest some time into this, too. What would be a good place to start? |
So, we need a way to forward certain API calls from the worker threads all the way up to the webpack compiler, get the result from the compiler, then pass them back down to the loaders running in the worker threads. This is for APIs like I've been keeping a list of the supported loader APIs in this wiki page. The first approach I took, see pull #15, was based around serializing the arguments for the API calls, sending them over to the main thread, asking the primary webpack compiler instance to carry out the routine, then forwarding back the (serialized) result. However, this isn't bullet-proof because some loaders actually rely on some The other approach I thought of was to spawn actual webpack compiler instances in each of the worker threads, with the configuration file that is used by the main thread. That way, those APIs would simply be handled by the in-process compiler instance. In theory, this should work for more cases than the first approach, but I'm not sure how fast it will be, especially when it comes to resolving because I know webpack caches a lot of things internally. |
@amireh Will do! |
@amireh My builds don't seem to finish unfortunately. My config: { test: /\.scss$/, loader: 'happypack/loader?id=sass' },
Thanks for your work! |
So, with the new changes in 2.0, it seems to work fine against react-redux-universal-hot-example. I ran it against // @file: react-redux-universal-hot-example/webpack/dev.config.js
var HappyPack = require('happypack');
var happyThreadPool = HappyPack.ThreadPool({ size: 5 });
// ...
module.exports = {
// ...
module: {
loaders: [
{ test: /\.jsx?$/, exclude: /node_modules/, loaders: ['babel?' + JSON.stringify(babelLoaderQuery), 'eslint-loader'], happy: { id: 'jsx' }, },
{ test: /\.json$/, loader: 'json-loader', happy: { id: 'json' } },
{ test: /\.less$/, loader: 'style!css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!less?outputStyle=expanded&sourceMap', happy: { id: 'less' } },
{ test: /\.scss$/, loader: 'style!css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap', happy: { id: 'sass' } },
{ test: /\.woff2?(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff", happy: { id: 'woff' } },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream", happy: { id: 'ttf' } },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file", happy: { id: 'eot' } },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml", happy: { id: 'svg' } },
{ test: webpackIsomorphicToolsPlugin.regular_expression('images'), loader: 'url-loader?limit=10240' }
]
},
// ...
plugins: [
// ...
new HappyPack({ id: 'jsx', enabled: true, threadPool: happyThreadPool, }),
new HappyPack({ id: 'json', enabled: true, threadPool: happyThreadPool, }),
new HappyPack({ id: 'less', enabled: true, threadPool: happyThreadPool, }),
new HappyPack({ id: 'sass', enabled: true, threadPool: happyThreadPool, }),
new HappyPack({ id: 'woff', enabled: true, threadPool: happyThreadPool, }),
new HappyPack({ id: 'ttf', enabled: true, threadPool: happyThreadPool, }),
new HappyPack({ id: 'eot', enabled: true, threadPool: happyThreadPool, }),
new HappyPack({ id: 'svg', enabled: true, threadPool: happyThreadPool, }),
]
}; The build used to take 11s without happypack, and now 6.7s with happypack. Obviously, you don't need to run it for the Let me know how it goes ! |
I was able to get huge speed-up react-redux-universal-hot-example with happypack v2. Great job!! First run:
Second run:
and found several bugs.
|
I don't think it's actually worth supporting
Even though the wiring is there, I still didn't implement source-map support. Primarily because I never worked with source-maps and I don't know what they look like when the loaders emit them; are they objects which can be serialized as JSON or are they plain text that can be written to a file directly? webpack docs are very scarce on this topic... If you guys can shed some light on this or point me to some resources, I can look into supporting them. (At work we just use
extract-text-webpack-plugin So I played a little bit more with the ExtractText plugin (after my failed attempts in #12) and I did found a workaround which isn't very optimal but it seems to work! I got the redux example repo to work with it (the // @file webpack/prod.config.js
var HappyPack = require('happypack');
var happyThreadPool = HappyPack.ThreadPool({ size: 5 });
// ...
module.exports = {
// ...
module: {
loaders: [
{ test: /\.jsx?$/, exclude: /node_modules/, loader: 'happypack/loader?id=jsx' },
{ test: /\.json$/, loader: 'happypack/loader?id=json' },
{ test: /\.less$/, loader: ExtractTextPlugin.extract('style', 'happypack/loader?id=less') },
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('style', 'happypack/loader?id=sass') },
// ...
]
},
plugins: [
// ...
createHappyPlugin('jsx', [strip.loader('debug'), 'babel']),
createHappyPlugin('json', [ 'json-loader' ]),
createHappyPlugin('less', [ 'css?modules&importLoaders=2&sourceMap!autoprefixer?browsers=last 2 version!less?outputStyle=expanded&sourceMap=true&sourceMapContents=true' ]),
createHappyPlugin('sass', [ 'css?modules&importLoaders=2&sourceMap!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap=true&sourceMapContents=true' ]),
],
// ...
};
function createHappyPlugin(id, loaders) {
return new HappyPack({
id: id,
loaders: loaders,
threadPool: happyThreadPool,
// disable happy caching with HAPPY_CACHE=0
cache: process.env.HAPPY_CACHE !== '0',
// make happy more verbose with HAPPY_VERBOSE=1
verbose: process.env.HAPPY_VERBOSE === '1',
});
} The trick was to happify all the loaders except for This is the configuration bit I'm talking about: {
loaders: [{ loader: ExtractTextPlugin.extract('style', 'happypack/loader?id=sass') }],
plugins: [new HappyPack({ id: 'sass', loaders: [ 'css', 'sass' ] })]
} If you guys can confirm that ExtractText is working this way, I will add this bit to the README and add it to the supported loaders list! Thanks |
I don't think it's needed too.
Passing loaders setting to HappyPack is working. Great job! |
Great! I'll update the docs when I get the chance, and open a ticket for SourceMap support. Closing this, thanks errybody. 👋 |
@amireh I get "loaderContext.loadModule is not a function" error in less-loader when I used the configuration in your comment. I'm using happypack^2.1.1 and less-loader 2.2.3 |
I'm getting the same problem as @jackfengji (same versions) |
@amireh I got a problem.
Finally the |
@jackfengji, @MagicDuck, regarding the @pigcan What is your problem exactly? Logs would be nice. |
When I use extract-text-webpack-plugin with happypack in my project I did found the css file would not minimize. |
@pigcan this can be solved by providing the query parameter to the css-loader, e.g. new HappyPack({ id: 'sass', loaders: [
'css?minimize', 'custom-autoprefixer',
'sass?includePaths=' + path.resolve(__dirname, './foundation/scss')
] }), |
I am getting the following error when trying your solution @amireh: [TypeError: Cannot read property 'applyPluginsWaterfall' of undefined] |
@amireh I use:
|
@amireh import webpack from 'webpack'
...
import createHappyPlugin, { getEnvId } from '../lib/createHappyPlugin'
export default {
resolve: {
modulesDirectories: [
'less',
'node_modules',
],
extensions: ['', '.js', '.jsx'],
},
module: {
loaders: [{
test: /\.less/,
loader: ExtractTextPlugin.extract('style', `happypack/loader?id=${getEnvId('less')}`),
// w/o HappyPack this works
// loader: ExtractTextPlugin.extract('style', [
// 'css?importLoaders=2&sourceMap',
// 'postcss-loader',
// 'less?outputStyle=expanded&sourceMap=true&sourceMapContents=true',
// ]),
}],
},
plugins: [
createHappyPlugin('less', [
'css?importLoaders=2&sourceMap',
'postcss-loader',
'less?outputStyle=expanded&sourceMap=true&sourceMapContents=true',
]),
new CleanPlugin([
path.resolve(__dirname, '../dist/bundles'),
], {
root: path.resolve(__dirname, '..'),
}),
new ExtractTextPlugin('[name].css', {
allChunks: true,
}),
],
postcss: () => [
pseudoelements,
autoprefixer,
cssmqpacker({ sort: true }),
csswring,
],
} import HappyPack from 'happypack'
const threadPool = HappyPack.ThreadPool({ size: 5 })
const env = process.env.NODE_ENV
export const getEnvId = (id) => `${env}-${id}`
const createHappyPlugin = (id, loaders) => new HappyPack({
id: getEnvId(id),
loaders,
threadPool,
// disable happy caching with HAPPY_CACHE=0
cache: process.env.HAPPY_CACHE !== '0',
// make happy more verbose with HAPPY_VERBOSE=1
verbose: process.env.HAPPY_VERBOSE === '1',
})
export default createHappyPlugin |
@AndyOGo @delijah This looks like plugins compatibility problem. I had the same and solved it with a custom loader: // webpack-autoprefixer.config.js
const autoprefixerBrowsers = ['> 0.5%', 'ie 9', 'ie 10'];
let autoprefixer = require('autoprefixer'),
postcss = require('postcss'),
processor = postcss([autoprefixer({ browsers: autoprefixerBrowsers })]);
module.exports = function (source) {
return processor.process(source);
} in fact this can be full postcss cycle loader, just change the name and the content. Then to use it: // webpack.config.js
new HappyPack({ id: 'sass', loaders: [
'css?minimize', 'custom-autoprefixer',
'sass?includePaths=' + path.resolve(__dirname, './foundation/scss')
] }),
// ...
module.exports = {
// ...
// allows to register a custom loader
resolveLoader: {
alias: { // custom-autoprefixer is used because there is no way to pass it to happypack otherwise
'custom-autoprefixer': path.join(__dirname, './webpack-autoprefixer.config.js')
}
}
// ... |
@smnbbrv |
This sounds more like a workaround than a solution, doesn't it? |
@delijah |
@delijah I am just trying to help, you can also wait for the bugfix :) |
@delijah |
Nonono. I didn't feel offended. Sorry if my comment did not sound politely, that was not my intention. So what i wanted to say: Thank you for your investigations. At the moment i prefer to hope/wait for a bugfix, but i think this workaround will help a lot of people that are dealing with the same error. Thanks again so far. |
I have this problem too in |
You're free to send a PR. :) |
ExtractTextPlugin.extract({ use: ['css-loader', 'sass-loader'] }) is breaking down pretty bad with large numbers of scss entries. I don't think this is related to happy-pack, I am seeing really bad performance with pure ExtractTextPlugin 2k + scss files. |
HappyPack is making us very happy, thanks for that!
How would I go about enabling happypack for this loader:
Cheers!
The text was updated successfully, but these errors were encountered: