1 | const pathConfig = require('config').get('path')
|
2 | const webpackConf = require('config').get('webpack')
|
3 | const path = require('path')
|
4 | const webpack = require('webpack')
|
5 | const SWPrecachePlugin = require('sw-precache-webpack-plugin')
|
6 | const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
|
7 | const VueLoaderPlugin = require('vue-loader/lib/plugin')
|
8 | const CleanWebpackPlugin = require('clean-webpack-plugin')
|
9 | const CopyWebpackPlugin = require('copy-webpack-plugin')
|
10 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
|
11 | const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
|
12 | const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
13 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
14 | const { NODE_ENV } = process.env
|
15 | const isProduction = NODE_ENV === 'production'
|
16 |
|
17 | const { alias } = require('./alias')
|
18 |
|
19 | const { publicPath } = require('./output.js')
|
20 |
|
21 | const { clientEntry } = require('./entry')
|
22 | const { entries: assetsEntry = {} } = webpackConf
|
23 |
|
24 | const webpackConfig = {
|
25 | target: 'web',
|
26 | mode: 'production',
|
27 | entry: Object.assign(
|
28 | {},
|
29 | assetsEntry,
|
30 | { global: pathConfig.global },
|
31 | clientEntry
|
32 | ),
|
33 | output: {
|
34 | filename: `js/[name].[chunkhash].js`,
|
35 | path: pathConfig.dist,
|
36 | publicPath: publicPath
|
37 | },
|
38 | resolve: {
|
39 | alias,
|
40 | extensions: ['.js', '.json', '.vue']
|
41 | },
|
42 | module: {
|
43 | rules: [
|
44 | {
|
45 | test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/,
|
46 | use: [
|
47 | {
|
48 | loader: 'url-loader',
|
49 | options: {
|
50 | limit: 10000,
|
51 | name: 'image/[name].[hash].[ext]'
|
52 | }
|
53 | }
|
54 | ]
|
55 | },
|
56 | {
|
57 | test: /\.js$/,
|
58 |
|
59 | use: [
|
60 | {
|
61 | loader: 'babel-loader',
|
62 | options: {
|
63 | presets: [
|
64 | [
|
65 | '@babel/preset-env',
|
66 | {
|
67 | targets: {
|
68 | browsers: ['Android >= 4.0', 'ios >= 6']
|
69 | },
|
70 | debug: true,
|
71 | include: [],
|
72 | useBuiltIns: false
|
73 | }
|
74 | ]
|
75 | ],
|
76 | plugins: ['@babel/plugin-syntax-dynamic-import']
|
77 | }
|
78 | }
|
79 | ]
|
80 | },
|
81 | {
|
82 | test: /\.vue$/,
|
83 | use: [
|
84 | {
|
85 | loader: 'vue-loader',
|
86 | options: {
|
87 | loaders: {
|
88 | css: [
|
89 | MiniCssExtractPlugin.loader,
|
90 | 'css-loader',
|
91 | 'vue-style-loader'
|
92 | ],
|
93 | sass: [
|
94 | MiniCssExtractPlugin.loader,
|
95 | 'css-loader',
|
96 | 'sass-loader',
|
97 | 'vue-style-loader'
|
98 | ],
|
99 | scss: [
|
100 | MiniCssExtractPlugin.loader,
|
101 | 'css-loader',
|
102 | 'sass-loader',
|
103 | 'vue-style-loader'
|
104 | ],
|
105 | js: {
|
106 | loader: 'babel-loader',
|
107 |
|
108 | options: {
|
109 | presets: [
|
110 | [
|
111 | '@babel/preset-env',
|
112 | {
|
113 | targets: {
|
114 | browsers: ['Android >= 4.0', 'ios >= 6']
|
115 | },
|
116 | debug: true,
|
117 | include: [],
|
118 | useBuiltIns: false
|
119 | }
|
120 | ]
|
121 | ],
|
122 | plugins: ['@babel/plugin-syntax-dynamic-import']
|
123 | }
|
124 | }
|
125 | }
|
126 | }
|
127 | }
|
128 | ]
|
129 | },
|
130 | {
|
131 | test: /\.css$/,
|
132 | use: [MiniCssExtractPlugin.loader, 'css-loader']
|
133 | },
|
134 | {
|
135 | test: /\.scss$/,
|
136 | use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
|
137 | },
|
138 | {
|
139 | test: /\.sass$/,
|
140 | use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
|
141 | }
|
142 | ]
|
143 | },
|
144 | plugins: [
|
145 | new VueLoaderPlugin(),
|
146 | new VueSSRClientPlugin(),
|
147 | new webpack.ProgressPlugin(),
|
148 | new webpack.DefinePlugin({
|
149 | 'process.env.buildTime': JSON.stringify(Date.now())
|
150 | }),
|
151 | new webpack.EnvironmentPlugin(['NODE_ENV']),
|
152 | new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
153 | new webpack.optimize.ModuleConcatenationPlugin(),
|
154 | new webpack.DllReferencePlugin({
|
155 | manifest: require(`${pathConfig.dll}/vendor.json`)
|
156 | }),
|
157 | new MiniCssExtractPlugin({
|
158 | filename: 'css/[name].[contenthash].css'
|
159 | }),
|
160 | new CleanWebpackPlugin(
|
161 | ['dist', 'static'],
|
162 | {
|
163 | root: pathConfig.root,
|
164 | exclude: ['favicon.ico', 'vue-ssr-server-bundle.json'],
|
165 | verbose: true,
|
166 | dry: false
|
167 | }
|
168 | )
|
169 |
|
170 |
|
171 |
|
172 |
|
173 | ],
|
174 | optimization: {
|
175 | minimizer: [
|
176 | new ParallelUglifyPlugin({
|
177 | uglifyES: {
|
178 | compress: {
|
179 | warnings: false,
|
180 | drop_console: isProduction
|
181 | }
|
182 | },
|
183 | exclude: ['vendor.js'],
|
184 | sourceMap: false
|
185 | }),
|
186 | new OptimizeCssAssetsPlugin({
|
187 | assetNameRegExp: /\.css$/g,
|
188 | cssProcessor: require('cssnano'),
|
189 | cssProcessorPluginOptions: {
|
190 | preset: ['default', { discardComments: { removeAll: true } }]
|
191 | },
|
192 | canPrint: true
|
193 | })
|
194 | ]
|
195 | },
|
196 | performance: {
|
197 | hints: false
|
198 | },
|
199 | stats: {
|
200 | colors: true,
|
201 | modules: false,
|
202 | children: false,
|
203 | chunks: false
|
204 | },
|
205 | devtool: 'false'
|
206 | }
|
207 |
|
208 | module.exports = { webpackConfig }
|