/* eslint-disable import/no-named-as-default-member */ const path = require('path'); const _ = require('lodash'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); // const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const WebpackPluginFrTheme = require('webpack-plugin-fr-theme'); const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin'); // const HardSourceWebpackPlugin = require('hard-source-webpack-plugin'); const CircularDependencyPlugin = require('circular-dependency-plugin'); const HardSourceWebpackPlugin = require('hard-source-webpack-plugin'); const HappyPack = require('happypack'); const os = require('os'); const getClientEnvironment = require('./env'); const paths = require('./paths'); const loaders = require('./loader.dev'); // const Jarvis = require('webpack-jarvis'); const publicUrl = ''; const contextPath = process.env._SETTING_CONTEXT_PATH; const env = getClientEnvironment(publicUrl); // 根据系统的内核数量 指定线程池个数 也可以其他数量 /*eslint-disable babel/new-cap */ const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }); module.exports = { mode: 'development', cache: true, entry: { app: [ // require.resolve('babel-polyfill'), 'webpack-dev-server/client?http://0.0.0.0:3000', 'webpack/hot/only-dev-server', paths.appIndexJs, ], vendor: [ 'react', 'prop-types', 'react-dom', 'react-router', 'react-router-dom', 'axios', 'lodash', 'moment', 'normalizr', ], }, // devtool: 'cheap-module-eval-source-map', devtool: 'cheap-module-source-map', // devtool: 'eval', output: { path: paths.appBuild, pathinfo: true, publicPath: '', filename: 'static/js/[name].[hash:7].js', sourceMapFilename: 'static/js/[name].[hash:7].map', chunkFilename: 'static/js/[name].[chunkhash:7].chunk.js', }, resolve: { modules: [paths.appSrc, paths.appNodeModules], extensions: ['.jsx', '.js', '.scss', '.css', '.json'], alias: { '@': paths.appSrc, }, plugins: [ // 阻止从src和node_modules目录之外导入模块 new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]), ], }, target: 'web', module: { rules: [ loaders.eslintLoader, { oneOf: [ { test: /\.(js|jsx)$/, use: `happypack/loader?id=babel`, exclude: /node_modules/, include: paths.appSrc, }, loaders.cssLoaderRule, loaders.scssLoaderRule, { test: /\.(less)$/, use: `happypack/loader?id=less`, }, loaders.svgSpriteLoader, loaders.fontWoffLoader, loaders.fontTtfLoader, loaders.mediaLoader, loaders.otherLoader, ], }, ], }, optimization: { namedModules: true, runtimeChunk: { name: 'manifest', }, splitChunks: { chunks: 'async', minSize: 30000, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, name: false, cacheGroups: { vendor: { name: 'vendor', chunks: 'initial', priority: -10, reuseExistingChunk: false, test: /node_modules\/(.*)\.js/, }, }, }, }, performance: { // 开启性能提示 hints: false, }, plugins: [ new WebpackPluginFrTheme(), new ProgressBarPlugin({ format: 'Build [:bar] :percent (:elapsed seconds)', clear: false, }), // new HardSourceWebpackPlugin(), new webpack.NamedModulesPlugin(), new webpack.optimize.ModuleConcatenationPlugin(), // 创建编译时配置的全局常量 new webpack.DefinePlugin(env.stringified), // 强制执行所有必需模块的整个路径,以匹配确切的大小写 new CaseSensitivePathsPlugin(), new CircularDependencyPlugin({ exclude: /node_modules/, failOnError: true, allowAsyncCycles: false, cwd: process.cwd(), }), new HappyPack({ id: 'babel', loaders: [loaders.jsLoader], threadPool: happyThreadPool, verbose: true, }), new HappyPack({ id: 'less', loaders: ['style-loader', loaders.cssLoaderConfig, loaders.postCssLoaderConfig, loaders.lessLoaderConfig], threadPool: happyThreadPool, verbose: true, }), new webpack.DllReferencePlugin({ manifest: require(path.join(paths.appDist, 'vendor.manifest.json')), sourceType: 'var', context: paths.appSrc, }), // new InterpolateHtmlPlugin(env.raw), new HtmlWebpackPlugin({ hash: false, // 为所有注入的静态资源添加webpack每次编译产生的唯一hash值 inject: true, // 向templateContent中注入所有静态资源,注入到body元素底部 template: paths.appHtml, sourceMap: true, basePath: _.isEmpty(contextPath) ? '/' : `/${contextPath}/`, }), new AddAssetHtmlPlugin([ { hash: true, filepath: require.resolve(path.join(paths.appDist, 'vendor.dll.js')), }, ]), // new Jarvis({ // port: 1337, // }), // 启用HRM new webpack.HotModuleReplacementPlugin(), /* eslint-disable no-useless-escape */ // 上下文替换插件(ContextReplacementPlugin) 允许你覆盖查找规则,减少打包时的local资源 new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en-gb|zh-cn/), // //模块提供中间缓存步骤 new HardSourceWebpackPlugin(), new HardSourceWebpackPlugin.ExcludeModulePlugin([ { // HardSource works with mini-css-extract-plugin but due to how // mini-css emits assets, assets are not emitted on repeated builds with // mini-css and hard-source together. Ignoring the mini-css loader // modules, but not the other css loader modules, excludes the modules // that mini-css needs rebuilt to output assets every time. test: /mini-css-extract-plugin[\\/]dist[\\/]loader/, }, ]), ], };