You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
5.4 KiB
220 lines
5.4 KiB
'use strict';
|
|
|
|
const exists = require('exists-file');
|
|
const webpack = require('webpack');
|
|
const HtmlPlugin = require('html-webpack-plugin');
|
|
const merge = require('deepmerge');
|
|
const preset = require('neutrino-preset-base');
|
|
const path = require('path');
|
|
const webpackMerge = require('webpack-merge').smart;
|
|
|
|
const CWD = process.cwd();
|
|
const SRC = path.join(CWD, 'src');
|
|
const PRESET_TEMPLATE_EJS = path.join(__dirname, 'template.ejs');
|
|
const PRESET_TEMPLATE_INDEX = path.join(__dirname, 'index.html');
|
|
const PROJECT_TEMPLATE = path.join(SRC, 'template.ejs');
|
|
const FILE_LOADER = require.resolve('file-loader');
|
|
const CSS_LOADER = require.resolve('css-loader');
|
|
const STYLE_LOADER = require.resolve('style-loader');
|
|
const URL_LOADER = require.resolve('url-loader');
|
|
const MODULES = path.join(__dirname, '../node_modules');
|
|
const USER_CONFIG = require(path.join(CWD, 'package.json'));
|
|
const VENDOR_LIBS = Object.keys(USER_CONFIG.dependencies);
|
|
|
|
preset.entry.index.unshift(require.resolve('babel-polyfill'));
|
|
|
|
/**
|
|
* Find best fit template.
|
|
*
|
|
* return preset template.ejs when no template found in project folder
|
|
*/
|
|
function findTemplate() {
|
|
if (exists.sync(PRESET_TEMPLATE_EJS)) {
|
|
return PRESET_TEMPLATE_EJS;
|
|
} else if (exists.sync(PRESET_TEMPLATE_INDEX)) {
|
|
return PRESET_TEMPLATE_INDEX;
|
|
}
|
|
|
|
return PROJECT_TEMPLATE;
|
|
}
|
|
|
|
const config = webpackMerge(preset, {
|
|
target: 'web',
|
|
node: {
|
|
console: false,
|
|
global: true,
|
|
process: true,
|
|
Buffer: true,
|
|
__filename: 'mock',
|
|
__dirname: 'mock',
|
|
setImmediate: true,
|
|
fs: 'empty',
|
|
tls: 'empty'
|
|
},
|
|
entry: {
|
|
vendor: VENDOR_LIBS
|
|
},
|
|
output: {
|
|
publicPath: './'
|
|
},
|
|
plugins: [
|
|
new webpack.EnvironmentPlugin(['NODE_ENV']),
|
|
new HtmlPlugin({
|
|
template: findTemplate(),
|
|
inject: 'body',
|
|
xhtml: true
|
|
}),
|
|
new webpack.LoaderOptionsPlugin({
|
|
options: {
|
|
eslint: {
|
|
configFile: path.join(__dirname, 'eslint.js')
|
|
}
|
|
}
|
|
})
|
|
],
|
|
resolve: {
|
|
modules: [MODULES]
|
|
},
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.html$/,
|
|
use: {
|
|
loader: FILE_LOADER,
|
|
options: {
|
|
name: '[name].[ext]'
|
|
}
|
|
}
|
|
},
|
|
{
|
|
test: /\.css$/,
|
|
loaders: [STYLE_LOADER, CSS_LOADER]
|
|
},
|
|
{
|
|
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
|
|
use: {
|
|
loader: URL_LOADER,
|
|
options: {
|
|
limit: 10000,
|
|
mimetype: 'application/font-woff'
|
|
}
|
|
}
|
|
},
|
|
{
|
|
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
|
|
use: {
|
|
loader: URL_LOADER,
|
|
options: {
|
|
limit: '10000',
|
|
mimetype: 'application/octet-stream'
|
|
}
|
|
}
|
|
},
|
|
{
|
|
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
|
|
use: FILE_LOADER
|
|
},
|
|
{
|
|
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
|
|
use: {
|
|
loader: URL_LOADER,
|
|
options: {
|
|
limit: '10000',
|
|
mimetype: 'application/svg+xml'
|
|
}
|
|
}
|
|
},
|
|
{
|
|
test: /\.(png|jpg)$/,
|
|
use: {
|
|
loader: URL_LOADER,
|
|
options: {
|
|
limit: 8192
|
|
}
|
|
}
|
|
},
|
|
{
|
|
test: /\.ico(\?v=\d+\.\d+\.\d+)?$/,
|
|
use: URL_LOADER
|
|
}
|
|
]
|
|
}
|
|
});
|
|
|
|
if (process.env.NODE_ENV !== 'test') {
|
|
config.plugins.push(new webpack.optimize.CommonsChunkPlugin({
|
|
names: ['vendor', 'manifest'],
|
|
minChunks: Infinity
|
|
}));
|
|
}
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
const protocol = !!process.env.HTTPS ? 'https' : 'http';
|
|
const host = process.env.HOST || 'localhost';
|
|
const port = parseInt(process.env.PORT) || 5000;
|
|
|
|
config.devServer = {
|
|
host,
|
|
port,
|
|
hot: true,
|
|
https: protocol === 'https',
|
|
contentBase: SRC,
|
|
// Enable history API fallback so HTML5 History API based
|
|
// routing works. This is a good default that will come
|
|
// in handy in more complicated setups.
|
|
historyApiFallback: true,
|
|
stats: {
|
|
colors: true,
|
|
chunks: false,
|
|
version: false,
|
|
assets: false,
|
|
modules: false,
|
|
children: false,
|
|
source: false
|
|
}
|
|
};
|
|
|
|
config.entry.index.push(`webpack-dev-server/client?${protocol}://${host}:${port}/`);
|
|
config.entry.index.push(`webpack/hot/dev-server`);
|
|
config.plugins.push(new webpack.HotModuleReplacementPlugin());
|
|
} else if (process.env.NODE_ENV === 'production') {
|
|
config.plugins.push(
|
|
new webpack.optimize.UglifyJsPlugin({ sourceMap: false, compress: { warnings: false }}),
|
|
new webpack.LoaderOptionsPlugin({ minimize: true })
|
|
);
|
|
} else if (process.env.NODE_ENV === 'test') {
|
|
config.karma = {
|
|
plugins: [
|
|
require.resolve('karma-webpack'),
|
|
require.resolve('karma-chrome-launcher'),
|
|
require.resolve('karma-coverage'),
|
|
require.resolve('karma-mocha'),
|
|
require.resolve('karma-mocha-reporter')
|
|
],
|
|
basePath: process.cwd(),
|
|
browsers: [process.env.CI ? 'ChromeCI' : 'Chrome'],
|
|
customLaunchers: {
|
|
ChromeCI: {
|
|
base: 'Chrome',
|
|
flags: ['--no-sandbox']
|
|
}
|
|
},
|
|
frameworks: ['mocha'],
|
|
files: ['test/**/*_test.js'],
|
|
preprocessors: {
|
|
'test/**/*_test.js': ['webpack'],
|
|
'src/**/*.js': ['webpack']
|
|
},
|
|
webpackMiddleware: { noInfo: true },
|
|
reporters: ['mocha', 'coverage'],
|
|
coverageReporter: {
|
|
dir: '.coverage',
|
|
reporters: [
|
|
{ type: 'html', subdir: 'report-html' },
|
|
{ type: 'lcov', subdir: 'report-lcov' }
|
|
]
|
|
}
|
|
};
|
|
}
|
|
|
|
module.exports = config;
|
|
|