Improve webpack configuration.

This commit is contained in:
Alexis Lahouze 2017-11-07 22:41:52 +01:00
parent c620a92250
commit b50d841862
11 changed files with 246 additions and 141 deletions

3
.gitignore vendored
View File

@ -81,4 +81,5 @@ tags
# End of https://www.gitignore.io/api/vim,node # End of https://www.gitignore.io/api/vim,node
/build /dist

10
config/helpers.js Normal file
View File

@ -0,0 +1,10 @@
var path = require('path');
var _root = path.resolve(__dirname, '..');
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [_root].concat(args));
}
exports.root = root;

125
config/webpack.common.js Normal file
View File

@ -0,0 +1,125 @@
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');
module.exports = {
entry: {
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'app': './src/main.ts',
'styles': './src/main.scss'
},
resolve: {
extensions: ['.ts', '.js'],
},
module: {
rules: [{
enforce: 'pre',
test: /webpack\.config\.js$/,
include: helpers.root('src', 'app'),
loader: 'eslint-loader',
options: {
useEslintrc: false,
emitWarning: true,
emitError: true,
failOnWarning: true,
failOnError: true,
baseConfig: 'webpack',
rules: {
indent: ['error', 4]
},
},
}, {
// Javascript
enforce: 'pre',
test: /\.jsx?$/,
include: helpers.root('src', 'app'),
loader: 'eslint-loader',
options: {
useEslintrc: false,
emitWarning: false,
emitError: true,
failOnWarning: false,
failOnError: true,
baseConfig: 'angular',
rules: {
indent: ['error', 4]
},
plugins: [
'angular',
'html',
'security',
'this',
'jquery',
'promise'
]
},
// }, {
// test: /\.jsx?$/,
// exclude: /node_modules/,
// loader: 'babel-loader'
}, {
test: /\.ts?$/,
//exclude: /node_modules/,
use: [
{
loader: 'awesome-typescript-loader',
options: { configFileName: helpers.root('src', 'tsconfig.json') }
},
'angular2-template-loader'
]
}, {
test: /\.html$/,
loader: 'html-loader'
}, {
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader',
]
}, {
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader?sourceMap'
})
}, {
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw-loader'
}, {
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
]
}, {
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[hash].[ext]'
}]
},
plugins: [
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)@angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/index.ejs'
})
],
};

32
config/webpack.dev.js Normal file
View File

@ -0,0 +1,32 @@
// vim: set tw=80 ts=2 sw=2 sts=2:
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
module.exports = webpackMerge(commonConfig, {
devtool: 'cheap-module-eval-source-map',
output: {
path: helpers.root('dist'),
publicPath: '/',
filename: '[name].js',
chunkFilename: '[id].chunk.js'
},
plugins: [
new ExtractTextPlugin('[name].css')
],
devServer: {
proxy: {
'/api': {
target: 'http://localhost:5000',
secure: false
}
},
historyApiFallback: true,
stats: 'minimal'
}
});

39
config/webpack.prod.js Normal file
View File

@ -0,0 +1,39 @@
/* jshint esversion: 6 */
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
module.exports = webpackMerge(commonConfig, {
devtool: 'source-map',
output: {
path: helpers.root('dist'),
publicPath: '/',
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].chunk.js'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
mangle: {
keep_fnames: true
}
}),
new ExtractTextPlugin('[name].[hash].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
}),
new webpack.LoaderOptionsPlugin({
htmlLoader: {
minimize: false // workaround for ng2
}
})
]
});

View File

@ -4,6 +4,8 @@
"repository": "https://git.lahouze.org/xals/accountant", "repository": "https://git.lahouze.org/xals/accountant",
"license": "AGPL-1.0", "license": "AGPL-1.0",
"devDependencies": { "devDependencies": {
"angular2-template-loader": "^0.6.2",
"awesome-typescript-loader": "^3.3.0",
"babel-core": "^6.26.0", "babel-core": "^6.26.0",
"babel-eslint": "^8.0.1", "babel-eslint": "^8.0.1",
"babel-loader": "^7.1.2", "babel-loader": "^7.1.2",
@ -36,7 +38,8 @@
"typescript": "^2.4.2", "typescript": "^2.4.2",
"url-loader": "^0.6.2", "url-loader": "^0.6.2",
"webpack": "^3.8.1", "webpack": "^3.8.1",
"webpack-dev-server": "^2.9.3" "webpack-dev-server": "^2.9.3",
"webpack-merge": "^4.1.1"
}, },
"dependencies": { "dependencies": {
"@angular/animations": "^4.4.6", "@angular/animations": "^4.4.6",
@ -65,7 +68,8 @@
"zone.js": "^0.8.17" "zone.js": "^0.8.17"
}, },
"scripts": { "scripts": {
"build": "webpack --config webpack.config.js", "build": "rm -Rf dist && webpack --config config/webpack.prod.js --progress --profile --bail",
"dev": "webpack-dev-server --debug --devtool eval --config webpack.config.js --progress --colors --hot --content-base build" "test": "karma start",
"dev": "webpack-dev-server --config config/webpack.dev.js --inline --progress --colors"
} }
} }

View File

@ -1,7 +1,12 @@
// vim: set tw=80 ts=2 sw=2 sts=2 : // vim: set tw=80 ts=2 sw=2 sts=2 :
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; if (process.env.ENV === 'production') {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule); platformBrowserDynamic().bootstrapModule(AppModule);

11
src/polyfills.ts Normal file
View File

@ -0,0 +1,11 @@
import 'core-js/es6';
import 'core-js/es7/reflect';
require('zone.js/dist/zone');
if (process.env.ENV === 'production') {
// Production
} else {
// Development and test
Error['stackTraceLimit'] = Infinity;
require('zone.js/dist/long-stack-trace-zone');
}

13
src/vendor.ts Normal file
View File

@ -0,0 +1,13 @@
// Angular
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
import '@angular/router';
// RxJS
import 'rxjs';
// Other vendors for example jQuery, Lodash or Bootstrap
// You can import js, ts, css, sass, ...

View File

@ -1,136 +1 @@
/* jshint esversion: 6 */ module.exports = require('./config/webpack.dev.js');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
context: path.resolve(__dirname, 'src'),
entry: {
"main": [
'./main.ts'
],
"styles": [
'./main.scss'
]
},
devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.html'],
},
module: {
rules: [{
enforce: 'pre',
test: /webpack\.config\.js$/,
include: path.resolve(__dirname),
loader: 'eslint-loader',
options: {
useEslintrc: false,
emitWarning: true,
emitError: true,
failOnWarning: true,
failOnError: true,
baseConfig: 'webpack',
rules: {
indent: ['error', 4]
},
},
}, {
// Javascript
enforce: 'pre',
test: /\.jsx?$/,
//include: path.resolve(__dirname, 'src'),
loader: 'eslint-loader',
options: {
useEslintrc: false,
emitWarning: false,
emitError: true,
failOnWarning: false,
failOnError: true,
baseConfig: 'angular',
rules: {
indent: ['error', 4]
},
plugins: [
'angular',
'html',
'security',
'this',
'jquery',
'promise'
]
},
}, {
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader'
}, {
test: /\.tsx?$/,
exclude: /node_modules/,
loader: 'ts-loader'
}, {
test: /\.html$/,
use: [
'ngtemplate-loader?relativeTo=/accountant-ui/src',
'html-loader'
]
}, {
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader',
]
}, {
test: /\.css$/,
use: [
'style-loader',
'css-loader',
]
}, {
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
]
}, {
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000'
}]
},
plugins: [
new webpack.ProvidePlugin({
"window.jQuery": "jquery"
}),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)@angular/,
path.resolve(__dirname, './')
),
new HtmlWebpackPlugin({
title: 'Accountant',
template: 'index.ejs',
hash: false,
inject: true,
compile: true,
minify: false,
chunks: 'all'
})
],
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].bundle.js',
chunkFilename: '[name].chunk.js'
//publicPath: 'js'
},
devServer: {
proxy: {
'/api': {
target: 'http://localhost:5000',
secure: false
}
},
hot: true,
noInfo: false,
quiet: false,
}
};