re-organize webpack configuration

- detach plugins configuration
 - use aliases
 - add project root to frontend module resolver
This commit is contained in:
Sérgio Ramos 2016-12-05 20:11:55 +00:00
parent 1d59d105ca
commit 0189d7d29a
10 changed files with 273 additions and 184 deletions

View File

@ -1,72 +1,55 @@
const ExtractTextPlugin = require('extract-text-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin');
const pkg = require('../package.json');
const webpack = require('webpack');
const WebpackShellPlugin = require('webpack-shell-plugin');
const path = require('path'); const path = require('path');
const fs = require('fs');
const plugins = { const plugins = require('./plugins');
'no-errors-plugin': new webpack.NoErrorsPlugin(), const CONTEXT = path.join(__dirname, '../src');
'extract-text-plugin': new ExtractTextPlugin({ const STATIC = path.join(__dirname, '../static');
filename: 'bundle.css', const ROOT = path.join(__dirname, '../..');
allChunks: true
}), module.exports = {
'loader-options-plugin': new webpack.LoaderOptionsPlugin({ context: CONTEXT,
options: { resolve: {
postcss: { modules: [
plugins: [ ROOT,
require('postcss-modules-values'), 'node_modules'
require('postcss-cssnext')() ],
] alias: fs.readdirSync(CONTEXT)
} .map((name) => path.join(CONTEXT, name))
} .filter((fullpath) => fs.statSync(fullpath).isDirectory())
}), .reduce((aliases, fullpath) => Object.assign(aliases, {
'define-plugin': new webpack.DefinePlugin({ [`@${path.basename(fullpath)}`]: fullpath
'process.env': { }), {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'), '@root': CONTEXT
APP_NAME: JSON.stringify(pkg.name),
APP_VERSION: JSON.stringify(pkg.version)
}
}),
'shell-plugin': new WebpackShellPlugin({
onBuildStart: ['npm run build-locales']
}) })
}; },
exports.config = {
context: path.join(__dirname, '../src'),
output: { output: {
path: path.join(__dirname, '../static'), path: STATIC,
publicPath: '/static/', publicPath: '/static/',
filename: 'bundle.js' filename: 'bundle.js'
}, },
plugins: [ plugins: [
plugins['no-errors-plugin'], plugins['no-errors'],
plugins['extract-text-plugin'], plugins['extract-text'],
plugins['loader-options-plugin'], plugins['loader-options'],
plugins['define-plugin'], plugins['define'],
plugins['shell-plugin'] plugins['shell']
], ],
module: { module: {
loaders: [{ loaders: [{
test: /js?$/, test: /js?$/,
exclude: /node_modules/, exclude: /node_modules/,
include: [ include: [CONTEXT],
path.join(__dirname, '../src') loaders: ['babel-loader']
],
loaders: ['babel']
}, { }, {
test: /\.json?$/, test: /\.json?$/,
exclude: /node_modules/, exclude: /node_modules/,
include: [ include: [CONTEXT],
path.join(__dirname, '../src') loaders: ['json-loader']
],
loaders: ['json']
}, { }, {
test: /\.css?$/, test: /\.css?$/,
exclude: /node_modules/, exclude: /node_modules/,
include: [ include: [CONTEXT],
path.join(__dirname, '../src')
],
loader: ExtractTextPlugin.extract({ loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader', fallbackLoader: 'style-loader',
loader: [ loader: [
@ -79,5 +62,3 @@ exports.config = {
}] }]
} }
}; };
exports.plugins = plugins;

View File

@ -1,30 +1,31 @@
const graphql = require('../../cloudapi-graphql/src/endpoint'); // const graphql = require('../../cloudapi-graphql/src/endpoint');
const base = require('./base.js'); const plugins = require('./plugins');
const webpack = require('webpack'); const base = require('./base');
const devServer = { const devServer = {
hot: true, hot: true,
compress: true, compress: true,
lazy: false, lazy: false,
publicPath: base.config.output.publicPath, publicPath: base.output.publicPath,
setup: (app) => { setup: (app) => {
app.use('/graphql', graphql); // app.use('/graphql', graphql);
}, },
historyApiFallback: { historyApiFallback: {
index: './static/index.html' index: './static/index.html'
} }
}; };
module.exports = Object.assign(base.config, { module.exports = Object.assign(base, {
devtool: 'eval-source-map',
entry: [ entry: [
'react-hot-loader/patch', 'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:8080', 'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server', 'webpack/hot/only-dev-server',
'./index.js' './index.js'
], ],
plugins: base.config.plugins.concat([ plugins: base.plugins.concat([
new webpack.HotModuleReplacementPlugin() plugins['named-modules'],
plugins['hot-module-replacement']
]), ]),
devtool: 'source-map',
devServer devServer
}); });

View File

@ -0,0 +1,45 @@
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const pkg = require('../package.json');
const webpack = require('webpack');
const WebpackShellPlugin = require('webpack-shell-plugin');
module.exports = {
'no-errors': new webpack.NoErrorsPlugin(),
'occurrence-order': new webpack.optimize.OccurrenceOrderPlugin(true),
'aggressive-merging': new webpack.optimize.AggressiveMergingPlugin(),
'hot-module-replacement': new webpack.HotModuleReplacementPlugin(),
'named-modules': new webpack.NamedModulesPlugin(),
'extract-text': new ExtractTextPlugin({
filename: 'bundle.css',
allChunks: true
}),
'loader-options': new webpack.LoaderOptionsPlugin({
options: {
postcss: {
plugins: [
require('postcss-modules-values'),
require('postcss-cssnext')()
]
}
}
}),
'define': new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
APP_NAME: JSON.stringify(pkg.name),
APP_VERSION: JSON.stringify(pkg.version)
}
}),
'shell': new WebpackShellPlugin({
onBuildStart: ['npm run build-locales']
}),
'uglify-js': new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
mangle: true,
output: {
comments: false,
indent_level: 2
}
})
};

View File

@ -1,16 +1,18 @@
const base = require('./base.js'); const plugins = require('./plugins');
const webpack = require('webpack'); const base = require('./base');
module.exports = Object.assign(base.config, {
module.exports = Object.assign(base, {
devtool: 'hidden-source-map',
entry: [ entry: [
'./index.js' './index.js'
], ],
plugins: base.config.plugins.concat([ plugins: base.plugins.concat([
new webpack.optimize.DedupePlugin(), plugins['named-modules']
new webpack.optimize.OccurrenceOrderPlugin(true), // plugins['occurrence-order'],
new webpack.optimize.UglifyJsPlugin() // plugins['aggressive-merging'],
]), // plugins['uglify-js']
devtool: 'eval' ])
}); });
/* /*

View File

@ -1,13 +1,13 @@
const base = require('./base'); const plugins = require('./plugins');
module.exports = { module.exports = {
output: { output: {
libraryTarget: 'commonjs2' libraryTarget: 'commonjs2'
}, },
plugins: [ plugins: [
base.plugins['no-errors-plugin'], plugins['no-errors-plugin'],
base.plugins['loader-options-plugin'], plugins['loader-options-plugin'],
base.plugins['define-plugin'] plugins['define-plugin']
], ],
module: { module: {
loaders: [{ loaders: [{

View File

@ -1,98 +1,48 @@
const ExtractTextPlugin = require('extract-text-webpack-plugin'); const gracefulFs = require('graceful-fs');
const webpack = require('webpack');
const path = require('path'); const path = require('path');
const cssFunctions = require('../src/shared/functions'); const fs = require('fs');
const plugins = { const plugins = require('./plugins');
'no-errors-plugin': new webpack.NoErrorsPlugin(),
'extract-text-plugin': new ExtractTextPlugin({
filename: 'css/[name].css',
allChunks: true
}),
'loader-options-plugin': new webpack.LoaderOptionsPlugin({
options: {
postcss: {
plugins: [
require('postcss-import')(),
require('postcss-constants')({}),
require('postcss-at-rules-variables')(),
require('postcss-functions')({
functions: cssFunctions
}),
require('postcss-mixins')({
mixinsFiles: path.join(__dirname, '../src/shared/mixins.css')
}),
require('postcss-for'),
require('postcss-cssnext')()
]
},
'embed-markdown-loader': {
mode: 'plain'
}
}
})
};
exports.config = { const CONTEXT = path.join(__dirname, '../');
context: path.join(__dirname, '../'), const STATIC = path.join(__dirname, '../static');
const SRC = path.join(__dirname, '../src');
const DOCS = path.join(__dirname, '../docs');
// PATCH `fs` to avoid ENFILE errors
gracefulFs.gracefulify(fs);
module.exports = {
devtool: 'eval',
context: CONTEXT,
entry: path.join(SRC, 'index.js'),
output: { output: {
path: path.join(__dirname, '../static'), path: STATIC,
publicPath: '/', publicPath: '/',
filename: 'js/[name].js' filename: '[name].js'
}, },
plugins: [ plugins: [
plugins['no-errors-plugin'], plugins['no-errors'],
plugins['extract-text-plugin'], plugins['extract-text'],
plugins['loader-options-plugin'] plugins['loader-options']
], ],
resolveLoader: {
alias: {
'embed-markdown-loader': path.join(__dirname, './embed-markdown-loader')
}
},
module: { module: {
loaders: [{ loaders: [{
test: /js?$/, test: /js?$/,
exclude: /node_modules/, exclude: /node_modules/,
include: [ include: [
path.join(__dirname, '../src'), SRC,
path.join(__dirname, '../docs') DOCS
], ],
loader: 'babel' loader: 'babel-loader'
}, { }, {
test: /\.json?$/, test: /\.json?$/,
exclude: /node_modules/, exclude: /node_modules/,
include: [ include: [
path.join(__dirname, '../src'), SRC,
path.join(__dirname, '../docs') DOCS
], ],
loader: 'json' loader: 'json-loader'
}, {
test: /\.md?$/,
exclude: /node_modules/,
include: [
path.join(__dirname, '../src'),
path.join(__dirname, '../docs')
],
loader: 'raw-loader!embed-markdown-loader'
}, {
test: /\.css?$/,
exclude: /node_modules/,
include: [
path.join(__dirname, '../src'),
path.join(__dirname, '../docs')
],
loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: [
'css-loader?',
'modules&importLoaders=1&',
'localIdentName=[name]__[local]___[hash:base64:5]!',
'postcss-loader'
].join('')
})
}] }]
} }
}; };
exports.plugins = plugins;

View File

@ -1,11 +1,16 @@
const pkg = require('../package.json'); const ExtractTextPlugin = require('extract-text-webpack-plugin');
const base = require('./base.js'); const plugins = require('./plugins');
const webpack = require('webpack'); const base = require('./base');
const path = require('path'); const path = require('path');
const EmbedMarkdownLoader = path.join(__dirname, './embed-markdown-loader');
const STATIC = path.join(__dirname, '../static');
const SRC = path.join(__dirname, '../src');
const DOCS = path.join(__dirname, '../docs');
const devServer = { const devServer = {
contentBase: [ contentBase: [
path.join(__dirname, '../static/') STATIC
], ],
hot: true, hot: true,
compress: true, compress: true,
@ -15,7 +20,7 @@ const devServer = {
} }
}; };
module.exports = Object.assign(base.config, { module.exports = Object.assign(base, {
entry: { entry: {
docs: [ docs: [
'react-hot-loader/patch', 'react-hot-loader/patch',
@ -24,16 +29,42 @@ module.exports = Object.assign(base.config, {
'./docs/index.js' './docs/index.js'
] ]
}, },
plugins: base.config.plugins.concat([ resolveLoader: {
new webpack.HotModuleReplacementPlugin(), alias: {
new webpack.DefinePlugin({ 'embed-markdown-loader': EmbedMarkdownLoader
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
APP_NAME: JSON.stringify(pkg.name),
APP_VERSION: JSON.stringify(pkg.version)
} }
}) },
plugins: base.plugins.concat([
plugins['named-modules'],
plugins['hot-module-replacement'],
plugins['define']
]), ]),
devtool: 'source-map', module: Object.assign(base.module, {
loaders: base.module.loaders.concat([{
test: /\.md?$/,
exclude: /node_modules/,
include: [
SRC,
DOCS
],
loader: 'raw-loader!embed-markdown-loader'
}, {
test: /\.css?$/,
exclude: /node_modules/,
include: [
SRC,
DOCS
],
loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: [
'css-loader?',
'modules&importLoaders=1&',
'localIdentName=[name]__[local]___[hash:base64:5]!',
'postcss-loader'
].join('')
})
}])
}),
devServer devServer
}); });

62
ui/webpack/plugins.js Normal file
View File

@ -0,0 +1,62 @@
const WebpackShellPlugin = require('webpack-shell-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const webpack = require('webpack');
const path = require('path');
const cssFunctions = require('../src/shared/functions');
const mixins = path.join(__dirname, '../src/shared/mixins.css');
const pkg = require('../package.json');
module.exports = {
'occurrence-order': new webpack.optimize.OccurrenceOrderPlugin(true),
'aggressive-merging': new webpack.optimize.AggressiveMergingPlugin(),
'hot-module-replacement': new webpack.HotModuleReplacementPlugin(),
'named-modules': new webpack.NamedModulesPlugin(),
'no-errors': new webpack.NoErrorsPlugin(),
'extract-text': new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
}),
'loader-options': new webpack.LoaderOptionsPlugin({
options: {
postcss: {
plugins: [
require('postcss-import')(),
require('postcss-constants')({}),
require('postcss-at-rules-variables')(),
require('postcss-functions')({
functions: cssFunctions
}),
require('postcss-mixins')({
mixinsFiles: mixins
}),
require('postcss-for'),
require('postcss-cssnext')()
]
},
'embed-markdown-loader': {
mode: 'plain'
}
}
}),
'define': new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
APP_NAME: JSON.stringify(pkg.name),
APP_VERSION: JSON.stringify(pkg.version)
}
}),
'uglify-js': new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
mangle: true,
output: {
comments: false,
indent_level: 2
}
}),
'shell': new WebpackShellPlugin({
onBuildEnd: [
'npm run build-docs-static'
]
})
};

View File

@ -1,25 +1,42 @@
const WebpackShellPlugin = require('webpack-shell-plugin');
const base = require('./base.js');
const webpack = require('webpack');
const entries = require('./entrypoints');
const path = require('path'); const path = require('path');
module.exports = Object.assign(base.config, { const plugins = require('./plugins');
entry: entries.reduce((all, entry) => { const base = require('./base');
all[entry.name] = [`./${path.relative(base.config.context, entry.path)}`]; const entries = require('./entrypoints');
const SRC = path.join(__dirname, '../src');
module.exports = Object.assign(base, {
output: Object.assign(base.output, {
libraryTarget: 'commonjs2'
}),
entry: entries.filter((entry) => {
return entry.name !== 'docs';
}).reduce((all, entry) => {
all[entry.name] = [`./${path.relative(base.context, entry.path)}`];
return all; return all;
}, {}), }, {}),
plugins: base.config.plugins.concat([ plugins: base.plugins.concat([
new webpack.optimize.DedupePlugin(), plugins['occurrence-order'],
new webpack.optimize.OccurrenceOrderPlugin(true), plugins['aggressive-merging'],
new webpack.optimize.UglifyJsPlugin(), plugins['uglify-js']
new WebpackShellPlugin({
onBuildEnd: [
'npm run build-docs-static'
]
})
]), ]),
devtool: 'eval' module: Object.assign(base.module, {
loaders: base.module.loaders.concat([{
test: /\.css?$/,
exclude: /node_modules/,
include: [
SRC
],
loader: [
'style-loader!',
'css-loader?',
'modules&importLoaders=1&',
'localIdentName=[name]__[local]___[hash:base64:5]!',
'postcss-loader'
].join('')
}])
})
}); });
/* /*

View File

@ -1,12 +1,12 @@
const base = require('./base'); const plugins = require('./plugins');
module.exports = { module.exports = {
output: { output: {
libraryTarget: 'commonjs2' libraryTarget: 'commonjs2'
}, },
plugins: [ plugins: [
base.plugins['no-errors-plugin'], plugins['no-errors'],
base.plugins['loader-options-plugin'] plugins['loader-options']
], ],
module: { module: {
loaders: [{ loaders: [{