-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebpack.config.js
152 lines (141 loc) · 4.47 KB
/
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const EventHooksPlugin = require('event-hooks-webpack-plugin');
const version = '1';
function extractLicenceComments(file) {
const content = fs.readFileSync(file, 'utf8');
const comments = content.match(/\/\*![^*]*\*+([^\/*][^*]*\*+)*\//g);
const licenseComments = [];
if (comments) {
comments.forEach(comment => {
licenseComments.push(comment);
});
// write licence comments to a separate file
fs.writeFileSync(`${file}.LICENSE.txt`, licenseComments.join('\r\n'));
// remove comments from css file
fs.writeFileSync(file, content.replace(/\/\*![^*]*\*+([^\/*][^*]*\*+)*\//g, ''));
}
}
module.exports = {
mode: 'production',
devtool: 'source-map',
watch: true,
stats: 'errors-only',
performance: {
hints: false,
},
optimization: {
usedExports: true,
},
cache: { type: 'filesystem' },
entry: {
...Object.fromEntries(
glob.sync('./views/ts/*.ts').map(file => [
`js/${path.relative('./views/ts', file).replace(/\\/g, '/').replace(/\\.ts$/, '')}`,
`./${file}`
])
),
...Object.fromEntries(
glob.sync('./views/scss/[^_]*.scss').map(file => [
`css/${path.relative('./views/scss', file).replace(/\\/g, '/').replace(/\\.scss$/, '')}`,
`./${file}`
])
)
},
output: {
filename: (pathData) => {
const ext = path.extname(pathData.chunk.name);
const name = pathData.chunk.name.replace(/\.(scss|ts)$/, '');
return ext === '.ts' ? `${name}-v${version}.min.js` : `${name}-v${version}.min.js`;
},
path: path.resolve(__dirname, 'dist'),
clean: true,
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: false,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('autoprefixer')(),
],
},
},
},
'sass-loader',
],
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
plugins: [
new MiniCssExtractPlugin({
filename: `[name].css`,
}),
new CopyWebpackPlugin({
patterns: [
{
from: 'views/assets',
to: 'assets',
noErrorOnMissing: true,
},
],
}),
new EventHooksPlugin({
'invalid': () => {
console.log('\r\n');
console.log(`> recompile: ${(new Date()).toLocaleTimeString()}`);
},
'done': (stats) => {
const time = stats.compilation.endTime - stats.compilation.startTime;
console.log(`> \x1b[32m${time}ms\x1b[0m`);
Object.entries(stats.compilation.assets).forEach(asset => {
try {
// if path contain css but file has .js extension, remove it
if (path.extname(asset[0]) == '.js' && asset[0].includes('css')) fs.unlinkSync(path.resolve(__dirname, 'dist', asset[0]));
// if file has .scss.css.map extension, remove it
if (path.extname(asset[0]) == '.map' && asset[0].includes('.scss.css')) fs.unlinkSync(path.resolve(__dirname, 'dist', asset[0]));
// if file has .scss.css extension, rename it to .css
if (path.extname(asset[0]) == '.css' && asset[0].includes('.scss.css')) fs.renameSync(path.resolve(__dirname, 'dist', asset[0]), path.resolve(__dirname, 'dist', asset[0].replace('.scss.css', `-v${version}.min.css`)));
// if file has .css extension, call extractLicenceComments on previously renamed file
if (path.extname(asset[0]) == '.css') extractLicenceComments(path.resolve(__dirname, 'dist', asset[0].replace('.scss.css', `-v${version}.min.css`)));
} catch (e) { }
});
}
})
],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin(),
new CssMinimizerPlugin({
minimizerOptions: {
preset: ['default', { discardComments: { removeAll: false } }],
},
}),
],
},
};