Skip to content
This repository has been archived by the owner on Jul 6, 2021. It is now read-only.

Commit

Permalink
Implement mini-css-extract-plugin (#228)
Browse files Browse the repository at this point in the history
* Implement mini-css-extract-plugin

* Update all css related plugins

* Upgrade devdev to webpack 4

* Update usage documentation

* Make sure extract is only ran on client compilation
  • Loading branch information
timneutkens authored Jul 29, 2018
1 parent f8ae948 commit 0735096
Show file tree
Hide file tree
Showing 16 changed files with 1,621 additions and 1,139 deletions.
23 changes: 0 additions & 23 deletions packages/next-css/commons-chunk-config.js

This file was deleted.

68 changes: 54 additions & 14 deletions packages/next-css/css-loader-config.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,69 @@
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const findUp = require('find-up')

const fileExtensions = new Set()
let extractCssInitialized = false

module.exports = (
config,
extractPlugin,
{ cssModules = false, cssLoaderOptions = {}, postcssLoaderOptions = {}, dev, isServer, loaders = [] }
{
extensions = [],
cssModules = false,
cssLoaderOptions = {},
dev,
isServer,
postcssLoaderOptions,
loaders = []
}
) => {
// We have to keep a list of extensions for the splitchunk config
for (const extension of extensions) {
fileExtensions.add(extension)
}

if (!isServer) {
config.optimization.splitChunks.cacheGroups.styles = {
name: 'styles',
test: new RegExp(`\\.+(${[...fileExtensions].join('|')})$`),
chunks: 'all',
enforce: true
}
}

if (!isServer && !extractCssInitialized) {
config.plugins.push(
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: dev
? 'static/css/[name].css'
: 'static/css/[name].[contenthash:8].css',
chunkFilename: dev
? 'static/css/[name].chunk.css'
: 'static/css/[name].[contenthash:8].chunk.css'
})
)
extractCssInitialized = true
}

const postcssConfig = findUp.sync('postcss.config.js', {
cwd: config.context
})
let postcssLoader

if (postcssConfig) {
//Copy the postcss-loader config options first.
postcssOptionsConfig = Object.assign(
// Copy the postcss-loader config options first.
const postcssOptionsConfig = Object.assign(
{},
postcssLoaderOptions.config,
{ path: postcssConfig }
)

postcssLoader = {
loader: 'postcss-loader',
options: Object.assign(
{},
postcssLoaderOptions,
{ config: postcssOptionsConfig }
)
options: Object.assign({}, postcssLoaderOptions, {
config: postcssOptionsConfig
})
}
}

Expand Down Expand Up @@ -53,9 +92,10 @@ module.exports = (
}

return [
dev && 'extracted-loader',
...extractPlugin.extract({
use: [cssLoader, postcssLoader, ...loaders].filter(Boolean)
})
!isServer && dev && 'extracted-loader',
!isServer && MiniCssExtractPlugin.loader,
cssLoader,
postcssLoader,
...loaders
].filter(Boolean)
}
}
23 changes: 3 additions & 20 deletions packages/next-css/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const cssLoaderConfig = require('./css-loader-config')
const commonsChunkConfig = require('./commons-chunk-config')

module.exports = (nextConfig = {}) => {
return Object.assign({}, nextConfig, {
Expand All @@ -13,24 +11,9 @@ module.exports = (nextConfig = {}) => {

const { dev, isServer } = options
const { cssModules, cssLoaderOptions, postcssLoaderOptions } = 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

if (!extractCSSPlugin) {
extractCSSPlugin = new ExtractTextPlugin({
filename: 'static/style.css'
})
config.plugins.push(extractCSSPlugin)
options.extractCSSPlugin = extractCSSPlugin
if (!isServer) {
config = commonsChunkConfig(config)
}
}

options.defaultLoaders.css = cssLoaderConfig(config, extractCSSPlugin, {
options.defaultLoaders.css = cssLoaderConfig(config, {
extensions: ['css'],
cssModules,
cssLoaderOptions,
postcssLoaderOptions,
Expand All @@ -50,4 +33,4 @@ module.exports = (nextConfig = {}) => {
return config
}
})
}
}
4 changes: 2 additions & 2 deletions packages/next-css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
"repository": "zeit/next-plugins",
"dependencies": {
"css-loader": "0.28.9",
"extract-text-webpack-plugin": "3.0.2",
"extracted-loader": "1.0.4",
"find-up": "2.1.0",
"ignore-loader": "0.1.2",
"mini-css-extract-plugin": "^0.4.1",
"postcss-loader": "2.0.10"
},
"devDependencies": {
"webpack": "^3.10.0"
"webpack": "^4.16.3"
}
}
24 changes: 2 additions & 22 deletions packages/next-css/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,8 @@ yarn add @zeit/next-css

## Usage

The stylesheet is compiled to `.next/static/style.css`. You have to include it into the page using a custom [`_document.js`](https://github.com/zeit/next.js#custom-document). The file will be served from `/_next/static/style.css`

```js
// ./pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document'

export default class MyDocument extends Document {
render() {
return (
<html>
<Head>
<link rel="stylesheet" href="/_next/static/style.css" />
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
```
The stylesheet is compiled to `.next/static/css`. Next.js will automatically add the css file to the HTML.
In production a chunk hash is added so that styles are updated when a new version of the stylesheet is deployed.

### Without CSS modules

Expand Down
21 changes: 2 additions & 19 deletions packages/next-less/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
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')

module.exports = (nextConfig = {}) => {
return Object.assign({}, nextConfig, {
Expand All @@ -18,24 +16,9 @@ module.exports = (nextConfig = {}) => {
postcssLoaderOptions,
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

if (!extractCSSPlugin) {
extractCSSPlugin = new ExtractTextPlugin({
filename: 'static/style.css'
})
config.plugins.push(extractCSSPlugin)
options.extractCSSPlugin = extractCSSPlugin
if (!isServer) {
config = commonsChunkConfig(config, /\.less$/)
}
}

options.defaultLoaders.less = cssLoaderConfig(config, extractCSSPlugin, {
options.defaultLoaders.less = cssLoaderConfig(config, {
extensions: ['less'],
cssModules,
cssLoaderOptions,
postcssLoaderOptions,
Expand Down
1 change: 0 additions & 1 deletion packages/next-less/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"repository": "zeit/next-plugins",
"dependencies": {
"@zeit/next-css": "0.2.0",
"extract-text-webpack-plugin": "3.0.2",
"less-loader": "4.1.0"
},
"devDependencies": {
Expand Down
24 changes: 2 additions & 22 deletions packages/next-less/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,8 @@ yarn add @zeit/next-less less

## Usage

The stylesheet is compiled to `.next/static/style.css`. You have to include it into the page using a custom [`_document.js`](https://github.com/zeit/next.js#custom-document). The file will be served from `/_next/static/style.css`

```js
// ./pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document'

export default class MyDocument extends Document {
render() {
return (
<html>
<Head>
<link rel="stylesheet" href="/_next/static/style.css" />
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
```
The stylesheet is compiled to `.next/static/css`. Next.js will automatically add the css file to the HTML.
In production a chunk hash is added so that styles are updated when a new version of the stylesheet is deployed.

### Without CSS modules

Expand Down
21 changes: 2 additions & 19 deletions packages/next-sass/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
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')

module.exports = (nextConfig = {}) => {
return Object.assign({}, nextConfig, {
Expand All @@ -18,24 +16,9 @@ module.exports = (nextConfig = {}) => {
postcssLoaderOptions,
sassLoaderOptions = {}
} = 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

if (!extractCSSPlugin) {
extractCSSPlugin = new ExtractTextPlugin({
filename: 'static/style.css'
})
config.plugins.push(extractCSSPlugin)
options.extractCSSPlugin = extractCSSPlugin
if (!isServer) {
config = commonsChunkConfig(config, /\.(scss|sass)$/)
}
}

options.defaultLoaders.sass = cssLoaderConfig(config, extractCSSPlugin, {
options.defaultLoaders.sass = cssLoaderConfig(config, {
extensions: ['scss', 'sass'],
cssModules,
cssLoaderOptions,
postcssLoaderOptions,
Expand Down
1 change: 0 additions & 1 deletion packages/next-sass/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"repository": "zeit/next-plugins",
"dependencies": {
"@zeit/next-css": "0.2.0",
"extract-text-webpack-plugin": "3.0.2",
"sass-loader": "6.0.6"
},
"devDependencies": {
Expand Down
26 changes: 3 additions & 23 deletions packages/next-sass/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,8 @@ yarn add @zeit/next-sass node-sass

## Usage

The stylesheet is compiled to `.next/static/style.css`. You have to include it into the page using a custom [`_document.js`](https://github.com/zeit/next.js#custom-document). The file will be served from `/_next/static/style.css`

```js
// ./pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document'

export default class MyDocument extends Document {
render() {
return (
<html>
<Head>
<link rel="stylesheet" href="/_next/static/style.css" />
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
```
The stylesheet is compiled to `.next/static/css`. Next.js will automatically add the css file to the HTML.
In production a chunk hash is added so that styles are updated when a new version of the stylesheet is deployed.

### Without CSS modules

Expand Down Expand Up @@ -126,7 +106,7 @@ import css from "../style.scss"

const Component = props => {
return (
<div className={css.backdrop}>
<div className={css.example}>
...
</div>
)
Expand Down
8 changes: 4 additions & 4 deletions packages/next-source-maps/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ module.exports = (nextConfig = {}) => {
const { dev } = options

if (!dev) {
config.devtool = 'source-map';
config.devtool = 'source-map'

for (const plugin of config.plugins) {
if (plugin['constructor']['name'] === 'UglifyJsPlugin') {
plugin.options.sourceMap = true;
break;
if (plugin.constructor.name === 'UglifyJsPlugin') {
plugin.options.sourceMap = true
break
}
}
}
Expand Down
Loading

0 comments on commit 0735096

Please sign in to comment.