I need to use @zeit/next-css and @zeit/next-sass at the same time, but this is failing by just using module.exports = withCSS(withSass(...)) as only one type gets compiled.
I'm trying to provide a simple example including the result map to get the issue resolved. I'm referencing to the issues
https://github.com/zeit/next-plugins/issues/34
https://github.com/zeit/next-plugins/issues/69
https://github.com/zeit/next-plugins/issues/58
https://github.com/zeit/next.js/issues/3852
This is a simple example what I'm doing and what the result looks like.
static/styles/style.css
#content {
font-size: 3rem
}
static/styles/style.sass
#title
font-size: 1rem
````
**next.config.js**
```javascript
const withCSS = require('@zeit/next-css')
const withSass = require('@zeit/next-sass')
module.exports = withCSS(withSass({
webpack: (config) => {
return config
}
}))
components/Header.js
import Head from 'next/head'
import '/static/styles/style.css'
import '/static/styles/style.sass'
export const Header = props => {
return (
<Head>
<meta httpEquiv='content-type' content='text/html;charset=UTF-8' />
<meta charSet='utf-8' />
<title>Title</title>
<link rel='stylesheet' href='/_next/static/style.css' />
</Head>
)
}
The result /.next/static/style.css content is only:
```css
font-size: 1rem
}
/# sourceMappingURL=style.css.map/
````
I'm missing the compiled sass file.
If I switch next.config.js to withSass(withCSS({..})) the result is only:
```css
font-size: 3rem; }
/# sourceMappingURL=style.css.map/
````
The map for the last one is:
{"version":3,"sources":["/Users/project/static/styles/style.sass"],"names":[],"mappings":"AAAA;EACE,gBAAgB,EAAE","file":"static/style.css","sourcesContent":["#title {\n font-size: 3rem; }\n\n\n\n// WEBPACK FOOTER //\n// ./static/styles/style.sass"],"sourceRoot":""}
@jaqua
vendor.css and app.css). And it will not resolve your problem.Your trouble can be fixed by recalling commonsChunkConfig with correct extensions:
const withCSS = require('@zeit/next-css')
const withSass = require('@zeit/next-sass')
const commonsChunkConfig = require('@zeit/next-css/commons-chunk-config')
module.exports = withCSS(withSass({
webpack: (config, { isServer }) => {
if (!isServer) {
config = commonsChunkConfig(config, /\.(sass|scss|css)$/)
}
return config
}
}))
The reason of that bug is CommonChunkPlugin which is working just for one extension (withCSS pass undefined and it used /.css$/, sass pass /.(sass|scss)$/, etc). You can find it here and here
Currently on next 5.1.0
This doesn't work for me in production, especially the SSR, and if I view the generated css files directly. I have a library used called namespace-ee/react-calendar-timeline on github, and by including the library it also requires the css file directly.
import Timeline from 'react-calendar-timeline/lib';
I'm using this method because nextjs doesn't support some typescript/flow thing in there by default.
And I notice in production, the css included by the timeline keeps overwriting my other default scss which I included later in the page.
None of the solutions above works for me. (e.g. next-compose, commonsChunkConfig)
Edit
Nvm, turns out one of my package was outdated (@zeit/next-css was v0.1.2), after upgraded to the latest (v0.1.5) it works working SSR now.
even with suggestions from @JerryCauser it doesn't work for me.
I have a project with antd (less) and my own sass stylesheets and the result is:
a) if I don't include my sass file - less get's compiled, but sass doesn't
b) if I do - less doesn't, sass does
I've come across two issues at the same time which are #21 and this one.
This is because, I use some third party libraries which required to include css (react-datepicker). And I prefer to develop component using SASS instead of styled jsx (I haven't use less)
In the end, I've create withSSSS to combine all css, sass, scss, less and it seem to solve my case (may be this case)
```javascript
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const cssLoaderConfig = require('@zeit/next-css/css-loader-config')
const commonsChunkConfig = require('@zeit/next-css/commons-chunk-config')
const MergeFilesPlugin = require('merge-files-webpack-plugin')
module.exports = (nextConfig = {}) => {
return Object.assign({}, nextConfig, {
webpack(config, options) {
if (!options.defaultLoaders) {
throw new Error(
'This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade'
)
}
const { dev, isServer } = options
const {
cssModules,
cssLoaderOptions,
postcssLoaderOptions,
sassLoaderOptions = {},
lessLoaderOptions = {},
} = nextConfig
// Support the user providing their own instance of ExtractTextPlugin.
// If extractCSSPlugin is not defined we pass the same instance of ExtractTextPlugin to all css related modules
// So that they compile to the same file in production
let extractCSSPlugin =
nextConfig.extractCSSPlugin || options.extractCSSPlugin
//the ORIGINAL from next-css
if (!extractCSSPlugin) {
extractCSSPlugin = new ExtractTextPlugin({
filename: 'static/style.css'
})
config.plugins.push(extractCSSPlugin)
options.extractCSSPlugin = extractCSSPlugin
if (!isServer) {
config = commonsChunkConfig(config, /\.(sass|scss|less|css)$/)
}
}
//the OVERWRITTEN
//using MergeFilesPlugin to combile all css files into one file
//ref: https://github.com/zeit/next-plugins/issues/21
if (!isServer && !dev) {
// Override next-css configuration
options.extractCSSPlugin.filename = 'static/[name].css';
// Merge all CSS in one file
config.plugins.push(
new MergeFilesPlugin({
filename: 'static/style.css',
test: /\.css/,
deleteSourceFiles: true,
})
)
}
options.defaultLoaders.css = cssLoaderConfig(config, extractCSSPlugin, {
cssModules,
cssLoaderOptions,
postcssLoaderOptions,
dev,
isServer
})
options.defaultLoaders.sass = cssLoaderConfig(config, extractCSSPlugin, {
cssModules,
cssLoaderOptions,
postcssLoaderOptions,
dev,
isServer,
loaders: [
{
loader: 'sass-loader',
options: sassLoaderOptions
}
]
})
options.defaultLoaders.less = cssLoaderConfig(config, extractCSSPlugin, {
cssModules,
cssLoaderOptions,
postcssLoaderOptions,
dev,
isServer,
loaders: [
{
loader: 'less-loader',
options: lessLoaderOptions
}
]
})
config.module.rules.push({
test: /\.css$/,
use: options.defaultLoaders.css
})
config.module.rules.push({
test: /\.scss$/,
use: options.defaultLoaders.sass
},{
test: /\.sass$/,
use: options.defaultLoaders.sass
})
config.module.rules.push({
test: /\.less$/,
use: options.defaultLoaders.less
})
if (typeof nextConfig.webpack === 'function') {
return nextConfig.webpack(config, options)
}
return config
}
})
}
````
@supadits Have you considered creating an NPM package for withSSSS?
Most helpful comment
@jaqua
58 is just another pattern for combining plugins. It gives additional functionality (every plugin has his own config), but it will be useful if #55 will be merged. Then will be easy to create 2 or more style files (for example
vendor.cssandapp.css). And it will not resolve your problem.Your trouble can be fixed by recalling
commonsChunkConfigwith correct extensions:The reason of that bug is CommonChunkPlugin which is working just for one extension (withCSS pass undefined and it used /.css$/, sass pass /.(sass|scss)$/, etc). You can find it here and here