-
Notifications
You must be signed in to change notification settings - Fork 59
Expand file tree
/
Copy pathwebpack.common.js
More file actions
116 lines (107 loc) · 4.62 KB
/
Copy pathwebpack.common.js
File metadata and controls
116 lines (107 loc) · 4.62 KB
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
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
const path = require('path')
const webpack = require('webpack')
const webpackConfig = require('@nextcloud/webpack-vue-config')
const CopyPlugin = require('copy-webpack-plugin')
webpackConfig.plugins.push(new CopyPlugin({
patterns: [
{ from: 'node_modules/twemoji/2/svg/', to: '../img/twemoji' },
],
}))
webpackConfig.entry = {
adminSettings: path.join(__dirname, 'src', 'adminSettings.js'),
social: path.join(__dirname, 'src', 'main.js'),
ostatus: path.join(__dirname, 'src', 'ostatus.js'),
profilePage: path.join(__dirname, 'src', 'profile.js'),
dashboard: path.join(__dirname, 'src', 'dashboard.js'),
oauth: path.join(__dirname, 'src', 'oauth.js'),
filesAction: path.join(__dirname, 'src', 'filesAction.js'),
}
// The one entry that stays self-contained. It registers "Share to Social" in
// the Files app and is loaded on every Files page, most of which will never
// post anything: a few KB of @nextcloud/files and l10n it can carry itself,
// the megabyte of framework it must not ask for. Excluded from the shared
// chunk below, so `FilesScriptsListener` loads it alone — on purpose, and
// `tests/js/bundles.test.js` pins that it works alone.
const SELF_CONTAINED = ['filesAction']
// Vue's build-time flags. Without them the bundle carries the devtools
// bridge into production — `@vue/devtools-api` pulls in `@vue/devtools-kit`,
// 170 KB of source that nothing in a released app can use — and Vue keeps the
// hydration-mismatch reporting it only needs while developing.
webpackConfig.plugins.push(new webpack.DefinePlugin({
__VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: 'false',
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
}))
// Scope hoisting stays off, as it has been since 0.9.3. It is worth 1.1 KB of
// the main entry, and with it on two consecutive builds of the same source
// produce two different bundles — Terser mangles the merged scopes differently
// — which would make CI's check that the committed js/ matches src/ fail about
// half the time.
webpackConfig.optimization.concatenateModules = false
// The emoji picker is most of a megabyte, and it was landing in the same
// vendor chunk as NcActionButton — which every post's overflow menu needs — so
// everybody downloaded the whole emoji set to see a "..." button. Give it a
// chunk of its own and it arrives when somebody opens the picker.
webpackConfig.optimization.splitChunks = {
...(webpackConfig.optimization.splitChunks ?? {}),
cacheGroups: {
...(webpackConfig.optimization.splitChunks?.cacheGroups ?? {}),
// Vue, @nextcloud/vue, pinia and the rest of the framework were built
// into each of the five entry points separately, so somebody who opened
// the Dashboard and then the app downloaded all of it twice — 1,116 KB
// and then 1,460 KB, most of it the same bytes. `chunks: 'initial'`
// takes third-party code out of the entries and leaves it in one file
// they share, which the browser then has cached. Async chunks keep the
// splitting they already had, and the emoji group below still wins for
// the picker because it has the higher priority.
//
// An entry is no longer self-contained, so every `Util::addScript()`
// for this app loads `social-framework` first — see `templates/`,
// `AdminSettings`, `SocialWidget` and `ProfileSectionListener`.
framework: {
test: /[\\/]node_modules[\\/]/,
name: 'framework',
chunks: (chunk) => chunk.canBeInitial() && !SELF_CONTAINED.includes(chunk.name),
// only what more than one entry point needs: a library just one of
// them uses stays in it, so opening the app alone downloads no more
// than it did before
minChunks: 2,
priority: 20,
reuseExistingChunk: true,
enforce: true,
},
emoji: {
test: /[\\/]node_modules[\\/](?:emoji-mart|emoji-mart-vue-fast)[\\/]/,
name: 'emoji-picker',
chunks: 'all',
priority: 30,
reuseExistingChunk: true,
enforce: true,
},
},
}
webpackConfig.module.rules.unshift({
test: /\.mjs$/,
type: 'javascript/auto',
resolve: {
fullySpecified: false,
},
})
webpackConfig.module.rules.unshift({
test: /node_modules\/(?:axios|webdav|@vue\/devtools-shared)\/.*\.js$/,
resolve: {
fullySpecified: false,
},
})
webpackConfig.resolve.extensions = ['.*', '.ts', '.js', '.vue', '.json']
// Preserve .htaccess when cleaning the output directory. It is the one file in
// js/ that is not build output; the administration page's script was the other
// one until that page became a Vue entry like every other.
webpackConfig.output.clean = {
keep: /\.htaccess/,
}
module.exports = webpackConfig