diff --git a/build/webpack.js b/build/webpack.js
index dc2695f0..725d2ffb 100644
--- a/build/webpack.js
+++ b/build/webpack.js
@@ -41,7 +41,7 @@ function externalsConfig (dir, isServer) {
}
// Webpack itself has to be compiled because it doesn't always use module relative paths
- if (res.match(/node_modules[/\\]webpack/)) {
+ if (res.match(/node_modules[/\\]webpack/) || res.match(/node_modules[/\\]css-loader/)) {
return callback()
}
@@ -59,7 +59,6 @@ function externalsConfig (dir, isServer) {
function optimizationConfig ({dir, dev, isServer, totalPages}) {
if (isServer) {
return {
- // runtimeChunk: 'single',
splitChunks: false,
minimize: false
}
@@ -69,7 +68,12 @@ function optimizationConfig ({dir, dev, isServer, totalPages}) {
runtimeChunk: {
name: CLIENT_STATIC_FILES_RUNTIME_WEBPACK
},
- splitChunks: false
+ splitChunks: {
+ cacheGroups: {
+ default: false,
+ vendors: false
+ }
+ }
}
if (dev) {
@@ -79,21 +83,14 @@ function optimizationConfig ({dir, dev, isServer, totalPages}) {
// Only enabled in production
// This logic will create a commons bundle
// with modules that are used in 50% of all pages
- return {
- ...config,
- splitChunks: {
- chunks: 'all',
- cacheGroups: {
- default: false,
- vendors: false,
- commons: {
- name: 'commons',
- chunks: 'all',
- minChunks: totalPages > 2 ? totalPages * 0.5 : 2
- }
- }
- }
+ config.splitChunks.chunks = 'all'
+ config.splitChunks.cacheGroups.commons = {
+ name: 'commons',
+ chunks: 'all',
+ minChunks: totalPages > 2 ? totalPages * 0.5 : 2
}
+
+ return config
}
type BaseConfigContext = {|
diff --git a/build/webpack/plugins/build-manifest-plugin.js b/build/webpack/plugins/build-manifest-plugin.js
index 9959614d..473474ee 100644
--- a/build/webpack/plugins/build-manifest-plugin.js
+++ b/build/webpack/plugins/build-manifest-plugin.js
@@ -8,7 +8,7 @@ export default class BuildManifestPlugin {
apply (compiler: any) {
compiler.hooks.emit.tapAsync('NextJsBuildManifest', (compilation, callback) => {
const {chunks} = compilation
- const assetMap = {pages: {}, css: []}
+ const assetMap = {pages: {}}
const mainJsChunk = chunks.find((c) => c.name === CLIENT_STATIC_FILES_RUNTIME_MAIN)
const mainJsFiles = mainJsChunk && mainJsChunk.files.length > 0 ? mainJsChunk.files.filter((file) => /\.js$/.test(file)) : []
@@ -35,12 +35,16 @@ export default class BuildManifestPlugin {
}
for (const file of chunk.files) {
- // Only `.js` files are added for now. In the future we can also handle other file types.
- if (/\.map$/.test(file) || /\.hot-update\.js$/.test(file) || !/\.js$/.test(file)) {
+ if (/\.map$/.test(file) || /\.hot-update\.js$/.test(file)) {
continue
}
- // These are manually added to _document.js
+ // Only `.js` and `.css` files are added for now. In the future we can also handle other file types.
+ if (!/\.js$/.test(file) && !/\.css$/.test(file)) {
+ continue
+ }
+
+ // The page bundles are manually added to _document.js as they need extra properties
if (IS_BUNDLED_PAGE_REGEX.exec(file)) {
continue
}
@@ -52,35 +56,6 @@ export default class BuildManifestPlugin {
assetMap.pages[`/${pagePath.replace(/\\/g, '/')}`] = [...filesForEntry, ...mainJsFiles]
}
- for (const chunk of chunks) {
- if (!chunk.name || !chunk.files) {
- continue
- }
-
- const files = []
-
- for (const file of chunk.files) {
- if (/\.map$/.test(file)) {
- continue
- }
-
- if (/\.hot-update\.js$/.test(file)) {
- continue
- }
-
- if (/\.css$/.exec(file)) {
- assetMap.css.push(file)
- continue
- }
-
- files.push(file)
- }
-
- if (files.length > 0) {
- assetMap[chunk.name] = files
- }
- }
-
if (typeof assetMap.pages['/index'] !== 'undefined') {
assetMap.pages['/'] = assetMap.pages['/index']
}
diff --git a/build/webpack/plugins/nextjs-ssr-module-cache.js b/build/webpack/plugins/nextjs-ssr-module-cache.js
index 176c910f..c09b3651 100644
--- a/build/webpack/plugins/nextjs-ssr-module-cache.js
+++ b/build/webpack/plugins/nextjs-ssr-module-cache.js
@@ -1,6 +1,7 @@
import webpack from 'webpack'
import { RawSource } from 'webpack-sources'
import { join, relative, dirname } from 'path'
+import {IS_BUNDLED_PAGE_REGEX} from '../../../lib/constants'
const SSR_MODULE_CACHE_FILENAME = 'ssr-module-cache.js'
@@ -31,7 +32,14 @@ export default class NextJsSsrImportPlugin {
compilation.mainTemplate.hooks.localVars.intercept({
register (tapInfo) {
if (tapInfo.name === 'MainTemplate') {
+ const originalFn = tapInfo.fn
tapInfo.fn = (source, chunk) => {
+ // If the chunk is not part of the pages directory we have to keep the original behavior,
+ // otherwise webpack will error out when the file is used before the compilation finishes
+ // this is the case with mini-css-extract-plugin
+ if (!IS_BUNDLED_PAGE_REGEX.exec(chunk.name)) {
+ return originalFn(source, chunk)
+ }
const pagePath = join(outputPath, dirname(chunk.name))
const relativePathToBaseDir = relative(pagePath, join(outputPath, SSR_MODULE_CACHE_FILENAME))
// Make sure even in windows, the path looks like in unix
diff --git a/package.json b/package.json
index 120e7cc0..47c34a04 100644
--- a/package.json
+++ b/package.json
@@ -99,7 +99,7 @@
"unfetch": "3.0.0",
"url": "0.11.0",
"uuid": "3.1.0",
- "webpack": "4.16.1",
+ "webpack": "4.16.3",
"webpack-dev-middleware": "3.1.3",
"webpack-hot-middleware": "2.22.2",
"webpack-sources": "1.1.0",
@@ -112,7 +112,8 @@
"@taskr/clear": "1.1.0",
"@taskr/esnext": "1.1.0",
"@taskr/watch": "1.1.0",
- "@zeit/next-css": "0.0.7",
+ "@zeit/next-css": "0.2.1-canary.1",
+ "@zeit/next-sass": "0.2.1-canary.1",
"@zeit/next-typescript": "1.1.0",
"babel-eslint": "8.2.2",
"babel-jest": "21.2.0",
@@ -135,6 +136,7 @@
"mkdirp": "0.5.1",
"node-fetch": "1.7.3",
"node-notifier": "5.1.2",
+ "node-sass": "4.9.2",
"nyc": "11.2.1",
"react": "16.4.0",
"react-dom": "16.4.0",
diff --git a/server/document.js b/server/document.js
index b77ab3e5..70c8a635 100644
--- a/server/document.js
+++ b/server/document.js
@@ -49,15 +49,41 @@ export class Head extends Component {
return null
}
- return files.map((file) => (
- {
+ // Only render .js files here
+ if(!/\.js$/.exec(file)) {
+ return null
+ }
+
+ return
- ))
+ })
+ }
+
+ getCssLinks () {
+ const { assetPrefix, files } = this.context._documentProps
+ if(!files || files.length === 0) {
+ return null
+ }
+
+ return files.map((file) => {
+ // Only render .css files here
+ if(!/\.css$/.exec(file)) {
+ return null
+ }
+
+ return
+ })
}
getPreloadDynamicChunks () {
@@ -85,6 +111,7 @@ export class Head extends Component {
{this.getPreloadDynamicChunks()}
{this.getPreloadMainLinks()}
+ {this.getCssLinks()}
{styles || null}
{this.props.children}
@@ -122,14 +149,19 @@ export class NextScript extends Component {
return null
}
- return files.map((file) => (
-