create webpack config with less support for both dev and prod

This commit is contained in:
Daniel Ternyak 2017-04-11 23:59:58 -05:00
parent fab71a19b4
commit 0fd652ab93
7 changed files with 309 additions and 0 deletions

18
webpack_config/config.js Normal file
View File

@ -0,0 +1,18 @@
'use strict'
const path = require('path')
module.exports = {
port: 3000,
title: 'React-Semantic.UI-starter',
publicPath: process.env.BUILD_GH_PAGES ? '/react-semantic.ui-starter/' : '/',
srcPath: path.join(__dirname, './../common'),
// add these dependencies to a standalone vendor bundle
vendor: [
'react', 'react-dom', 'react-router', 'redux', 'react-router-redux', 'redux-thunk', 'semantic-ui-react', 'whatwg-fetch', 'semantic-ui-css/semantic.css'
],
// enable babelrc
babel: {
babelrc: true
},
cssModules: false
}

View File

@ -0,0 +1,15 @@
'use strict'
const chalk = require('chalk')
// this plugin if for loggin url after each time the compilation is done.
module.exports = class LogPlugin {
constructor(port) {
this.port = port
}
apply(compiler) {
compiler.plugin('done', () => {
console.log(`> App is running at ${chalk.yellow(`http://localhost:${this.port}`)}\n`)
})
}
}

57
webpack_config/server.js Normal file
View File

@ -0,0 +1,57 @@
'use strict'
const path = require('path')
const express = require('express')
const webpack = require('webpack')
const webpackConfig = require('./webpack.dev')
const config = require('./config')
const LogPlugin = require('./log-plugin')
const app = express()
const port = config.port
webpackConfig.entry.client = [
'react-hot-loader/patch',
'webpack-hot-middleware/client?reload=true',
'webpack/hot/only-dev-server',
webpackConfig.entry.client
]
webpackConfig.plugins.push(new LogPlugin(port))
let compiler
try {
compiler = webpack(webpackConfig)
} catch (err) {
console.log(err.message)
process.exit(1)
}
const devMiddleWare = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: false,
inline: true,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Headers': '*'
}
})
app.use(devMiddleWare)
app.use(require('webpack-hot-middleware')(compiler, {
log: console.log
}))
const mfs = devMiddleWare.fileSystem
const file = path.join(webpackConfig.output.path, 'index.html')
devMiddleWare.waitUntilValid()
app.get('*', (req, res) => {
devMiddleWare.waitUntilValid(() => {
const html = mfs.readFileSync(file)
res.end(html)
})
})
app.listen(port)

28
webpack_config/utils.js Normal file
View File

@ -0,0 +1,28 @@
'use strict'
const path = require('path')
const config = require('./config')
const _ = module.exports = {}
_.cwd = (file) => {
return path.join(process.cwd(), file || '')
}
_.outputPath = path.join(__dirname, '../dist')
_.outputIndexPath = path.join(__dirname, '../dist/index.html')
_.target = 'web'
_.loadersOptions = () => {
const isProd = process.env.NODE_ENV === 'production'
return {
minimize: isProd,
options: {
// css-loader relies on context
context: process.cwd(),
babel: config.babel
}
}
}

View File

@ -0,0 +1,85 @@
'use strict'
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const config = require('./config')
const _ = require('./utils')
module.exports = {
entry: {
client: './common/index.jsx'
},
output: {
path: _.outputPath,
filename: '[name].js',
publicPath: config.publicPath
},
performance: {
hints: process.env.NODE_ENV === 'production'
? 'warning'
: false
},
resolve: {
extensions: [
'.js', '.jsx', '.css', '.json', '.scss', '.less'
],
alias: {
actions: `${config.srcPath}/actions/`,
api: `${config.srcPath}/api/`,
reducers: `${config.srcPath}/reducers/`,
components: `${config.srcPath}/components/`,
containers: `${config.srcPath}/containers/`,
styles: `${config.srcPath}/styles/`,
less_vars: `${config.srcPath}/styles/etherwallet-variables.less`,
scss_vars: `${config.srcPath}/styles/vars.scss`,
config: `${config.srcPath}/config/` + process.env.REACT_WEBPACK_ENV
},
modules: [
// places where to search for required modules
_.cwd('common'),
_.cwd('node_modules'),
_.cwd('./')
]
},
module: {
loaders: [
{
test: /\.(js|jsx)$/,
enforce: 'pre',
loaders: ['eslint-loader'],
exclude: [/node_modules/]
},
{
test: /\.(js|jsx)$/,
loaders: ['babel-loader'],
exclude: [/node_modules/]
}, {
test: /\.(ico|jpg|png|gif|eot|otf|webp|ttf|woff|woff2)(\?.*)?$/,
loader: 'file-loader?limit=100000'
}, {
test: /\.svg$/,
loader: 'file-loader'
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env.BUILD_GH_PAGES': JSON.stringify(!!process.env.BUILD_GH_PAGES)
}),
new HtmlWebpackPlugin({
title: config.title,
template: path.resolve(__dirname, '../common/index.html'),
filename: _.outputIndexPath
}),
new webpack.LoaderOptionsPlugin(_.loadersOptions()),
new CopyWebpackPlugin([
{
from: _.cwd('./static'),
// to the root of dist path
to: './'
}
])
],
target: _.target
}

View File

@ -0,0 +1,30 @@
'use strict'
process.env.NODE_ENV = 'development'
process.env.REACT_WEBPACK_ENV = 'dev'
const webpack = require('webpack')
const base = require('./webpack.base')
const FriendlyErrors = require('friendly-errors-webpack-plugin')
base.devtool = 'eval-source-map'
base.module.loaders.push({
test: /\.css$/,
loaders: ['style-loader', 'css-loader', 'resolve-url-loader']
}, {
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'resolve-url-loader', 'sass-loader']
},
{
test: /\.less$/,
loaders: ['style-loader', 'css-loader', 'resolve-url-loader', 'less-loader']
})
base.plugins.push(
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new FriendlyErrors()
)
module.exports = base

View File

@ -0,0 +1,76 @@
'use strict'
process.env.NODE_ENV = 'production'
process.env.REACT_WEBPACK_ENV = 'dist'
const exec = require('child_process').execSync
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const ProgressPlugin = require('webpack/lib/ProgressPlugin')
// const OfflinePlugin = require('offline-plugin')
const base = require('./webpack.base')
const config = require('./config')
exec('rm -rf dist/')
base.devtool = 'cheap-source-map'
base.module.loaders.push(
{
test: /\.css$/,
use: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader'})
}, {
test: /\.scss$/,
use: ExtractTextPlugin.extract({fallback: 'style-loader', use: ['css-loader', 'sass-loader']}),
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({fallback: 'style-loader', use: ['css-loader', 'sass-loader']})
}
)
// a white list to add dependencies to vendor chunk
base.entry.vendor = config.vendor
// use hash filename to support long-term caching
base.output.filename = '[name].[chunkhash:8].js'
// add webpack plugins
base.plugins.push(
new ProgressPlugin(),
new ExtractTextPlugin('[name].[chunkhash:8].css'),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
},
output: {
comments: false
}
}),
// extract vendor chunks
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.[chunkhash:8].js'
})
// For progressive web apps
// new OfflinePlugin({
// relativePaths: false,
// AppCache: false,
// ServiceWorker: {
// events: true
// }
// })
)
// minimize webpack output
base.stats = {
// Add children information
children: false,
// Add chunk information (setting this to `false` allows for a less verbose output)
chunks: false,
// Add built modules information to chunk information
chunkModules: false,
chunkOrigins: false,
modules: false
}
module.exports = base