1 |
|
2 |
|
3 | const webpack = require('webpack');
|
4 | const { join, resolve } = require('path');
|
5 | const Merge = require('webpack-merge');
|
6 | const { environment } = require('@rails/webpacker');
|
7 | const config = require('@rails/webpacker/package/config');
|
8 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
9 | const MinifyPlugin = require('babel-minify-webpack-plugin');
|
10 | const TerserPlugin = require('terser-webpack-plugin');
|
11 | var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
12 | const ImageminWebpWebpackPlugin = require('imagemin-webp-webpack-plugin');
|
13 | const WebpackAssetsManifest = require('webpack-assets-manifest');
|
14 | const { env } = require('process');
|
15 | const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
|
16 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
17 | const { getIfUtils, removeEmpty } = require('webpack-config-utils');
|
18 |
|
19 | const { ifProduction } = getIfUtils(env.NODE_ENV);
|
20 |
|
21 | const context = resolve(config.source_path);
|
22 | const loaderPath = resolve(__dirname + '/loaders');
|
23 |
|
24 | const assets = require(resolve(loaderPath, 'assets'));
|
25 | const styles = require(resolve(loaderPath, 'styles'));
|
26 |
|
27 | const uglifierSetting = {
|
28 | parallel: true,
|
29 | cache: true,
|
30 | sourceMap: true,
|
31 | terserOptions: {
|
32 | ie8: false,
|
33 | ecma: 7,
|
34 | warnings: false,
|
35 | mangle: false,
|
36 | compress: {
|
37 | warnings: false,
|
38 | comparisons: false,
|
39 | drop_console: true,
|
40 | },
|
41 |
|
42 |
|
43 |
|
44 | },
|
45 | };
|
46 |
|
47 | const entry = require('./entries');
|
48 | const source = resolve(config.source_path);
|
49 |
|
50 | const SetPath = (s, e) => (e ? resolve(s, e) : undefined);
|
51 |
|
52 | const modules = removeEmpty([
|
53 | resolve(source, config.source_entry_path),
|
54 | SetPath(source, config.image_entry),
|
55 | SetPath(source, config.stylesheets_entry),
|
56 | resolve('node_modules'),
|
57 | ]);
|
58 |
|
59 | environment.plugins.append(
|
60 | 'Manifest',
|
61 | new WebpackAssetsManifest({
|
62 | integrity: false,
|
63 | entrypoints: true,
|
64 | writeToDisk: true,
|
65 | publicPath: true,
|
66 | transform(imgs, manifest) {
|
67 | const regx = /.(jpg|png|jpeg)/;
|
68 | Object.entries(imgs).forEach(([k, v]) => {
|
69 | console.log('Testing', regx.test(k));
|
70 | if (regx.test(k)) {
|
71 | const { key, value } = manifest.hooks.customize.call({
|
72 | key: k.replace(regx, '.webp'),
|
73 | value: v.replace(regx, '.webp'),
|
74 | });
|
75 |
|
76 | imgs[key] = value;
|
77 | }
|
78 | });
|
79 |
|
80 |
|
81 | },
|
82 | })
|
83 | );
|
84 |
|
85 |
|
86 |
|
87 | environment.plugins.prepend(
|
88 | 'Lodash',
|
89 | new LodashModuleReplacementPlugin({
|
90 | collections: true,
|
91 | currying: true,
|
92 | shorthands: true,
|
93 |
|
94 |
|
95 | })
|
96 | );
|
97 |
|
98 | environment.plugins.prepend('CreateWebp', new ImageminWebpWebpackPlugin());
|
99 |
|
100 | environment.plugins.prepend(
|
101 | 'ExtractText',
|
102 | new MiniCssExtractPlugin({
|
103 | filename: ifProduction('[name]-[contenthash:8].css', '[name].css'),
|
104 | chunkFilename: '[name]-[contenthash:8].chunk.css',
|
105 | })
|
106 | );
|
107 |
|
108 | environment.plugins.prepend('Moment', new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en-gb/));
|
109 |
|
110 | environment.plugins.prepend(
|
111 | 'LoaderOptions',
|
112 | new webpack.LoaderOptionsPlugin(
|
113 | ifProduction(
|
114 | {
|
115 | minimize: true,
|
116 | debug: false,
|
117 | },
|
118 | {
|
119 | debug: true,
|
120 | }
|
121 | )
|
122 | )
|
123 | );
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 | if (ifProduction()) {
|
135 | environment.config.set('optimization.minimizer', [new TerserPlugin(uglifierSetting)]);
|
136 | environment.plugins.append('BabelMinify', new MinifyPlugin());
|
137 |
|
138 | environment.plugins.prepend(
|
139 | 'CssOptimize',
|
140 | new OptimizeCssAssetsPlugin({
|
141 | cssProcessor: require('cssnano'),
|
142 | cssProcessorPluginOptions: {
|
143 | preset: ['default', { discardComments: { removeAll: true } }],
|
144 | },
|
145 | canPrint: true,
|
146 | })
|
147 | );
|
148 | }
|
149 |
|
150 | environment.loaders.insert('file', assets(env.NODE_ENV));
|
151 | environment.config.set('context', context);
|
152 | environment.config.set('resolve.alias', {
|
153 | images: resolve(config.source_path, config.image_entry || 'images'),
|
154 | Images: resolve(config.source_path, config.image_entry || 'images'),
|
155 | });
|
156 |
|
157 | environment.config.set('output', {
|
158 | filename: '[name]-[chunkhash].js',
|
159 | chunkFilename: '[name]-[chunkhash].chunk.js',
|
160 | hotUpdateChunkFilename: '[id]-[hash].hot-update.js',
|
161 | path: config.outputPath,
|
162 | publicPath: config.publicPath,
|
163 | });
|
164 |
|
165 |
|
166 |
|
167 | module.exports = (cssHotReloading = false) => {
|
168 | environment.loaders.insert('css', styles(env.NODE_ENV, cssHotReloading));
|
169 | environment.loaders.insert('sass', styles(env.NODE_ENV, cssHotReloading, true));
|
170 | return { environment, entry };
|
171 | };
|