bsl
Version:
基于React的框架和UI组件
224 lines (220 loc) • 6.78 kB
text/typescript
/// <reference path="../typings/webpackConfig.d.ts" />
import * as path from 'path';
import * as fs from 'fs';
import * as webpack from 'webpack';
import BSL from '../typings';
interface Package {
version: string;
}
type Config = webpack.Configuration;
const env = process.env.NODE_ENV as BSL.Env;
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const isDev = env === 'development' ? true : false;
export default function webpackConfig(params: WebpackConfig): Config {
const { entry, dirname, publicPath, vender, cssModule } = params;
const sassResources = params.sassResources || [];
const addPlugins = params.plugins || [];
const addVersion = params.addVersion === false ? false : true;
const outputDir = params.outputDir || 'build';
const pkg: Package = JSON.parse(fs.readFileSync(path.resolve(dirname, 'package.json'), { encoding: 'utf8' }));
const version = pkg.version;
const filename = addVersion ? `[name]_${version}.js` : '[name].js';
const tsInclude = params.tsInclude || [];
const plugins = [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env),
'process.env.version': JSON.stringify(version),
'process.env.outputDir': JSON.stringify(outputDir),
'process.env.publicPath': JSON.stringify(publicPath),
'process.env.addVersion': JSON.stringify(addVersion)
}),
new webpack.NoEmitOnErrorsPlugin(),
new SpriteLoaderPlugin(),
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /de|fr|hu/),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new CleanWebpackPlugin(),
new ExtractTextPlugin({
filename: addVersion ? `css/[name]_${version}.css` : 'css/[name].css',
allChunks: true
}),
new webpack.WatchIgnorePlugin([
/\.d\.ts$/
]),
...addPlugins
];
const extract: any[] = [{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('autoprefixer')()
],
sourceMap: isDev
}
}, {
loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: isDev
}
}, {
loader: 'sass-resources-loader',
options: {
resources: [
path.resolve(__dirname, '../styles/mixins.scss'),
...sassResources
]
}
}];
if (cssModule !== false) {
extract.unshift({
loader: 'typings-for-css-modules-loader',
options: {
modules: true,
namedExport: true,
camelCase: true,
minimize: !isDev,
localIdentName: '[local]_[hash:base64:5]'
}
});
}
if (isDev && vender !== false) {
plugins.push(new webpack.DllReferencePlugin({
context: 'bsl',
manifest: require('../vender/manifest.json')
}));
}
// else {
// plugins.push(new webpack.optimize.ModuleConcatenationPlugin());
// }
return {
entry,
devtool: isDev ? 'inline-source-map' : false,
output: {
publicPath,
path: path.resolve(dirname, outputDir),
filename: './js/' + filename,
chunkFilename: 'js/' + filename
},
module: {
rules: [{
test: /\.(ts|tsx)$/,
enforce: 'pre',
loader: 'eslint-loader',
include: [
path.resolve(dirname, 'src'),
...tsInclude
]
}, {
test: /\.(ts|tsx)$/,
loader: 'ts-loader',
include: [
path.resolve(dirname, 'src'),
path.resolve(dirname, './node_modules/bsl'),
...tsInclude
]
}, {
test: /\.svg$/,
loader: 'svg-sprite-loader',
options: {
extract: true,
esModule: false,
symbolId: (filePath: string) => {
const indexOfStr = 'src' + path.sep;
const srcIndex = filePath.indexOf(indexOfStr);
const symbolId = filePath.substr(srcIndex + indexOfStr.length).replace('.svg', '').replace(/\/|\\/g, '_');
return symbolId;
},
spriteFilename: addVersion ? `/svg/sprite_${pkg.version}.svg` : `/svg/sprite.svg`
}
}, {
test: /\.(png|jpg|gif)$/,
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
outputPath: 'img/'
}
}, {
test: /\.html$/,
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
outputPath: 'html/'
}
}, {
test: /\.(mp3|ogg|wav)$/,
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
outputPath: 'audio/'
}
}, {
test: /\.(mp4|ogg|webm)$/,
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
outputPath: 'video/'
}
}, {
test: /\.md$/,
use: [{
loader: "raw-loader"
}]
}, {
test: /\.(scss)$/,
use: ExtractTextPlugin.extract({
use: extract
})
}]
},
resolve: {
alias: {
moment$: 'moment/moment.js'
},
extensions: ['.webpack.js', '.web.js', '.js', '.jsx', '.tsx', '.ts', '.web.ts', '.scss', '.css'],
modules: isDev ? [path.resolve(dirname, 'node_modules')] : undefined,
mainFields: isDev ? ['jsnext:main', 'main'] : undefined
},
plugins,
stats: {
children: false,
chunks: false,
chunkModules: false,
chunkOrigins: false,
entrypoints: false,
reasons: false,
source: false,
modules: false,
excludeAssets: [/\.(png|jpg|gif)$/]
},
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
ecma: 5,
compress: {
// 在UglifyJs删除没有用到的代码时不输出警告
warnings: false,
// 删除所有的 console 语句
// 还可以兼容ie浏览器
'drop_console': true,
// 内嵌定义了但是只用到一次的变量
'collapse_vars': true,
// 提取出出现多次但是没有定义成变量去引用的静态值
'reduce_vars': true
},
output: {
// 最紧凑的输出
beautify: false,
// 删除所有的注释
comments: false
}
}
})
]
}
};
}