Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack config refactor; CSS now generated with HTML #253

Merged
merged 4 commits into from
May 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions lib/utils/build-css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import webpack from 'webpack'
import webpackConfig from './webpack.config'
import fs from 'fs'

module.exports = (program, callback) => {
const { directory } = program

const compilerConfig = webpackConfig(program, directory, 'build-css')

return webpack(compilerConfig.resolve()).run((err, stats) => {
// We don't want any javascript produced by this step in the process.
fs.unlinkSync(`${directory}/public/bundle-for-css.js`)

return callback(err, stats)
})
}
11 changes: 8 additions & 3 deletions lib/utils/static-generation.js → lib/utils/build-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ require('node-cjsx').transform()
import webpack from 'webpack'
import globPages from './glob-pages'
import webpackConfig from './webpack.config'
const debug = require('debug')('gatsby:static')
import fs from 'fs'
const debug = require('debug')('gatsby:html')

module.exports = (program, callback) => {
const { directory } = program

globPages(directory, (err, pages) => {
debug('generating static site')
debug('generating static HTML')
const routes = pages.filter((page) => page.path).map((page) => page.path)

// Static site generation.
const compilerConfig = webpackConfig(program, directory, 'static', null, routes)
const compilerConfig = webpackConfig(program, directory, 'build-html', null, routes)

webpack(compilerConfig.resolve()).run((e, stats) => {
if (e) {
Expand All @@ -21,6 +22,10 @@ module.exports = (program, callback) => {
if (stats.hasErrors()) {
return callback(`Error: ${stats.toJson().errors}`, stats)
}

// A temp file required by static-site-generator-plugin
fs.unlinkSync(`${directory}/public/render-page.js`)

return callback(null, stats)
})
})
Expand Down
10 changes: 10 additions & 0 deletions lib/utils/build-javascript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import webpack from 'webpack'
import webpackConfig from './webpack.config'

module.exports = (program, callback) => {
const { directory } = program

const compilerConfig = webpackConfig(program, directory, 'build-javascript')

return webpack(compilerConfig.resolve()).run(callback)
}
11 changes: 0 additions & 11 deletions lib/utils/build-production.js

This file was deleted.

35 changes: 21 additions & 14 deletions lib/utils/build.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import generateStaticPages from './static-generation'
import buildProductionBundle from './build-production'
import buildCSS from './build-css'
import buildHTML from './build-html'
import buildProductionBundle from './build-javascript'
import postBuild from './post-build'
import globPages from './glob-pages'
import toml from 'toml'
Expand Down Expand Up @@ -62,7 +63,7 @@ function bundle (program, callback) {
}

function html (program, callback) {
console.log('Generating static html pages')
console.log('Generating static HTML/CSS')

const directory = program.directory
let config
Expand All @@ -73,19 +74,25 @@ function html (program, callback) {
callback(error)
}

generateStaticPages(program, (error) => {
if (error) {
console.log('failed at generating static html pages')
return callback(error)
buildCSS(program, (cssError) => {
if (cssError) {
console.log('Failed at generating styles.css')
return callback(cssError)
}

// If we're not generating a SPA, go directly to post build steps
if (config.noProductionJavascript) {
post(program, callback)
} else {
bundle(program, callback)
}
return true
return buildHTML(program, (htmlError) => {
if (htmlError) {
console.log('Failed at generating HTML')
return callback(htmlError)
}

// If we're not generating javascript, go directly to post build steps
if (config.noProductionJavascript) {
return post(program, callback)
} else {
return bundle(program, callback)
}
})
})
}

Expand Down
119 changes: 84 additions & 35 deletions lib/utils/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ try {
}
}

// Four stages:
// 1) develop: for `gatsby develop` command, hot reload and CSS injection into page
// 2) build-css: build styles.css file
// 3) build-html: build all HTML files
// 4) build-javascript: Build bundle.js for Single Page App in production

module.exports = (program, directory, stage, webpackPort = 1500, routes = []) => {
debug(`Loading webpack config for stage "${stage}"`)
function output () {
Expand All @@ -25,13 +31,22 @@ module.exports = (program, directory, stage, webpackPort = 1500, routes = []) =>
filename: 'bundle.js',
publicPath: `http://${program.host}:${webpackPort}/`,
}
case 'static':
case 'build-css':
// Webpack will always generate a resultant javascript file.
// But we don't want it for this step. Deleted by build-css.js.
return {
path: `${directory}/public`,
filename: 'bundle.js',
filename: 'bundle-for-css.js',
}
case 'build-html':
// A temp file required by static-site-generator-plugin. See plugins() below.
// Deleted by build-html.js, since it's not needed for production.
return {
path: `${directory}/public`,
filename: 'render-page.js',
libraryTarget: 'umd',
}
case 'production':
case 'build-javascript':
return {
filename: 'bundle.js',
path: `${directory}/public`,
Expand All @@ -48,14 +63,18 @@ module.exports = (program, directory, stage, webpackPort = 1500, routes = []) =>
require.resolve('webpack-hot-middleware/client'),
`${__dirname}/web-entry`,
]
case 'production':
case 'build-css':
return {
main: `${__dirname}/web-entry`,
}
case 'build-html':
return {
main: `${__dirname}/static-entry`,
}
case 'build-javascript':
return [
`${__dirname}/web-entry`,
]
case 'static':
return [
`${__dirname}/static-entry`,
]
default:
throw new Error(`The state requested ${stage} doesn't exist.`)
}
Expand All @@ -75,32 +94,41 @@ module.exports = (program, directory, stage, webpackPort = 1500, routes = []) =>
__PREFIX_LINKS__: program.prefixLinks,
}),
]
case 'production':
case 'build-css':
return [
// Moment.js includes 100s of KBs of extra localization data
// by default in Webpack that most sites don't want.
// This line disables that.
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV ? process.env.NODE_ENV : 'production'),
},
__PREFIX_LINKS__: program.prefixLinks,
}),
new webpack.optimize.DedupePlugin(),
new ExtractTextPlugin('styles.css'),
new webpack.optimize.UglifyJsPlugin(),
]
case 'static':
case 'build-html':
return [
new StaticSiteGeneratorPlugin('bundle.js', routes),
new StaticSiteGeneratorPlugin('render-page.js', routes),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV ? process.env.NODE_ENV : 'production'),
},
__PREFIX_LINKS__: program.prefixLinks,
}),
]
case 'build-javascript':
return [
// Moment.js includes 100s of KBs of extra localization data
// by default in Webpack that most sites don't want.
// This line disables that.
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV ? process.env.NODE_ENV : 'production'),
},
__PREFIX_LINKS__: program.prefixLinks,
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin(),
]
default:
throw new Error(`The state requested ${stage} doesn't exist.`)
}
Expand Down Expand Up @@ -135,9 +163,9 @@ module.exports = (program, directory, stage, webpackPort = 1500, routes = []) =>
switch (stage) {
case 'develop':
return 'eval'
case 'static':
case 'build-html':
return false
case 'production':
case 'build-javascript':
return 'source-map'
default:
return false
Expand Down Expand Up @@ -266,22 +294,7 @@ module.exports = (program, directory, stage, webpackPort = 1500, routes = []) =>
})
return config

case 'static':
config.loader('css', {
test: /\.css$/,
loaders: ['css'],
})
config.loader('less', {
test: /\.less/,
loaders: ['css', 'less'],
})
config.loader('sass', {
test: /\.(sass|scss)/,
loaders: ['css', 'sass'],
})
return config

case 'production':
case 'build-css':
config.loader('css', {
test: /\.css$/,
loader: ExtractTextPlugin.extract(['css', 'postcss']),
Expand All @@ -307,6 +320,42 @@ module.exports = (program, directory, stage, webpackPort = 1500, routes = []) =>
})
return config

case 'build-html':
// We don't deal with CSS at all when building the HTML.
// The 'null' loader is used to prevent 'module not found' errors.

config.loader('css', {
test: /\.css$/,
loader: 'null',
})
config.loader('less', {
test: /\.less/,
loader: 'null',
})
config.loader('sass', {
test: /\.(sass|scss)/,
loader: 'null',
})
return config

case 'build-javascript':
// We don't deal with CSS at all when building the javascript.
// The 'null' loader is used to prevent 'module not found' errors.

config.loader('css', {
test: /\.css$/,
loader: 'null',
})
config.loader('less', {
test: /\.less/,
loader: 'null',
})
config.loader('sass', {
test: /\.(sass|scss)/,
loader: 'null',
})
return config

default:
return config
}
Expand Down