|
@@ -0,0 +1,239 @@
|
|
|
+const webpack = require('webpack');
|
|
|
+const cssnano = require('cssnano');
|
|
|
+const pxtorem = require('postcss-pxtorem');
|
|
|
+const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
|
+const CleanWebpackPlugin = require('clean-webpack-plugin');
|
|
|
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
|
|
+const debug = require('debug')('app:webpack:config');
|
|
|
+const fs = require('fs');
|
|
|
+const config = require('../config');
|
|
|
+
|
|
|
+const paths = config.utils_paths;
|
|
|
+const { __DEV__, __PROD__ } = config.globals;
|
|
|
+
|
|
|
+function getPublicPath(path) {
|
|
|
+ const publicPath =
|
|
|
+ config.publicPath.substr(config.publicPath.length - 2, 1) === '/' ? config.publicPath : config.publicPath + '/';
|
|
|
+ if (path) {
|
|
|
+ path = path.indexOf('/') === 0 ? path.substr(1, path.length - 1) : path;
|
|
|
+ return publicPath + path;
|
|
|
+ } else {
|
|
|
+ return publicPath;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function fileNameFormat(type, ext) {
|
|
|
+ ext = ext || '[ext]';
|
|
|
+ return `src/[name].[${type}].${ext}`;
|
|
|
+}
|
|
|
+debug('Creating configuration.');
|
|
|
+
|
|
|
+const webpackConfig = {
|
|
|
+ name: 'client',
|
|
|
+ target: 'web',
|
|
|
+ cache: true,
|
|
|
+ resolve: {
|
|
|
+ extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
|
|
|
+ alias: {
|
|
|
+ '@src': paths.client(),
|
|
|
+ '@project': paths.project(),
|
|
|
+ '@components': paths.components(),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ module: {},
|
|
|
+ stats: config.compiler_stats,
|
|
|
+};
|
|
|
+
|
|
|
+if (config.compiler_devtool) webpackConfig.devtool = config.compiler_devtool;
|
|
|
+
|
|
|
+const APP_ENTRY = paths.client('main.js');
|
|
|
+const devApp = [
|
|
|
+ 'webpack/hot/dev-server',
|
|
|
+ `webpack-hot-middleware/client?path=${config.publicPath}__webpack_hmr`,
|
|
|
+ 'react-hot-loader/patch',
|
|
|
+ APP_ENTRY,
|
|
|
+];
|
|
|
+webpackConfig.entry = {
|
|
|
+ app: __DEV__ ? devApp : [APP_ENTRY],
|
|
|
+};
|
|
|
+
|
|
|
+webpackConfig.output = {
|
|
|
+ filename: fileNameFormat(config.compiler_hash_type, 'js'),
|
|
|
+ path: paths.dist(),
|
|
|
+ publicPath: getPublicPath(),
|
|
|
+ chunkFilename: fileNameFormat(config.compiler_hash_type, 'js'),
|
|
|
+};
|
|
|
+
|
|
|
+function getLibPath(path) {
|
|
|
+ let pach = null;
|
|
|
+ try {
|
|
|
+ fs.readdirSync(path).forEach(file => {
|
|
|
+ if (file.indexOf('lib') === 0) {
|
|
|
+ pach = file;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e);
|
|
|
+ }
|
|
|
+ return pach;
|
|
|
+}
|
|
|
+
|
|
|
+for (let i = 0; i < config.scripts.length; i += 1) {
|
|
|
+ const script = config.scripts[i];
|
|
|
+ if (script.indexOf('http') !== 0) {
|
|
|
+ config.scripts[i] = getPublicPath(script);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+config.scripts.push(getPublicPath(getLibPath(paths.lib())));
|
|
|
+
|
|
|
+webpackConfig.plugins = [
|
|
|
+ new webpack.DefinePlugin(config.globals),
|
|
|
+ new CleanWebpackPlugin(['*'], {
|
|
|
+ root: paths.dist(),
|
|
|
+ }),
|
|
|
+ new webpack.ProgressPlugin(),
|
|
|
+ new webpack.DllReferencePlugin({
|
|
|
+ context: paths.lib(),
|
|
|
+ manifest: paths.lib('manifest.json'),
|
|
|
+ extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
|
|
|
+ }),
|
|
|
+ new HtmlWebpackPlugin({
|
|
|
+ template: paths.client('index.html'),
|
|
|
+ hash: false,
|
|
|
+ minify: {
|
|
|
+ collapseWhitespace: true,
|
|
|
+ },
|
|
|
+ title: config.title,
|
|
|
+ filename: 'index.html',
|
|
|
+ inject: 'body',
|
|
|
+ globals: Object.assign(config.globals, {
|
|
|
+ keyword: config.keyword,
|
|
|
+ description: config.description,
|
|
|
+ scripts: config.scripts,
|
|
|
+ }),
|
|
|
+ }),
|
|
|
+ new webpack.LoaderOptionsPlugin({
|
|
|
+ options: {
|
|
|
+ postcss() {
|
|
|
+ return [
|
|
|
+ cssnano({
|
|
|
+ autoprefixer: {
|
|
|
+ add: true,
|
|
|
+ browsers: ['iOS >= 7', 'Android >= 4.1'],
|
|
|
+ },
|
|
|
+ discardComments: {
|
|
|
+ removeAll: true,
|
|
|
+ },
|
|
|
+ discardUnused: false,
|
|
|
+ mergeIdents: false,
|
|
|
+ reduceIdents: false,
|
|
|
+ safe: true,
|
|
|
+ sourcemap: true,
|
|
|
+ }),
|
|
|
+ pxtorem({
|
|
|
+ rootValue: 50,
|
|
|
+ propWhiteList: [],
|
|
|
+ }),
|
|
|
+ ];
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }),
|
|
|
+];
|
|
|
+if (__DEV__) {
|
|
|
+ webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin());
|
|
|
+} else {
|
|
|
+ webpackConfig.plugins.push(
|
|
|
+ // new webpack.optimize.CommonsChunkPlugin({
|
|
|
+ // name: ['app'],
|
|
|
+ // minChunks: function (module, count) {
|
|
|
+ // return module.context && module.context.indexOf('node_modules') !== -1
|
|
|
+ // }
|
|
|
+ // }),
|
|
|
+ new webpack.optimize.UglifyJsPlugin({
|
|
|
+ cache: true,
|
|
|
+ parallel: true,
|
|
|
+ }),
|
|
|
+ new ExtractTextPlugin({
|
|
|
+ filename: fileNameFormat(config.compiler_hash_type, 'css'),
|
|
|
+ allChunks: true,
|
|
|
+ }),
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+webpackConfig.module.rules = [
|
|
|
+ {
|
|
|
+ test: /\.(js|jsx)$/,
|
|
|
+ exclude: /node_modules/,
|
|
|
+ use: ['babel-loader', 'eslint-loader'],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ test: /\.yml$/,
|
|
|
+ use: ['json-loader', 'yaml-loader'],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ test: /\.json$/,
|
|
|
+ use: 'json-loader',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ test: /\.(svg)(\?.*)?$/,
|
|
|
+ include: paths.client(),
|
|
|
+ use: {
|
|
|
+ loader: 'url-loader',
|
|
|
+ options: {
|
|
|
+ limit: 10240,
|
|
|
+ name: fileNameFormat('hash'),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ test: /\.(png|jpe?g|gif)(\?.*)?$/,
|
|
|
+ use: {
|
|
|
+ loader: 'url-loader',
|
|
|
+ options: {
|
|
|
+ limit: 10240,
|
|
|
+ name: fileNameFormat('hash'),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
|
|
+ use: {
|
|
|
+ loader: 'url-loader',
|
|
|
+ options: {
|
|
|
+ limit: 10240,
|
|
|
+ name: fileNameFormat('hash'),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+function loaderAnalysis(loaders) {
|
|
|
+ if (__PROD__) {
|
|
|
+ return ExtractTextPlugin.extract({
|
|
|
+ fallback: loaders.shift(),
|
|
|
+ use: loaders,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return loaders;
|
|
|
+}
|
|
|
+
|
|
|
+const theme = {
|
|
|
+ // 'primary-color': '#f54b37'
|
|
|
+};
|
|
|
+
|
|
|
+webpackConfig.module.rules.push({
|
|
|
+ test: /\.css$/,
|
|
|
+ use: loaderAnalysis(['style-loader', 'css-loader', 'postcss-loader']),
|
|
|
+});
|
|
|
+webpackConfig.module.rules.push({
|
|
|
+ test: /\.less$/,
|
|
|
+ use: loaderAnalysis([
|
|
|
+ 'style-loader',
|
|
|
+ 'css-loader',
|
|
|
+ 'postcss-loader',
|
|
|
+ `less-loader?{'modifyVars':${JSON.stringify(theme)}}`,
|
|
|
+ ]),
|
|
|
+});
|
|
|
+
|
|
|
+module.exports = webpackConfig;
|