-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebpack.production.js
116 lines (111 loc) · 3.77 KB
/
webpack.production.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
const fs = require( 'fs' );
const rimraf = require( 'rimraf' );
const { mergeWithCustomize, customizeObject } = require( 'webpack-merge' );
const CommonConfig = require( './webpack.common.js' );
const MediaWikiTextWrapper = require( './webpack/mediawiki_text_wrapper' );
const LoadVueOnWpde = require( './webpack/load_vue_on_wpde' );
const CampaignConfig = require( './webpack/campaign_config' );
const path = require( 'path' );
function readWrapperTemplate( name ) {
// eslint-disable-next-line security/detect-non-literal-fs-filename
return fs.readFileSync( `./webpack/wikitext_templates/${name}.hbs`, 'utf8' );
}
module.exports = ( env ) => {
let entrypointRules = {};
let customizationRules = { customizeObject: () => undefined };
const campaigns = CampaignConfig.readFromFile( env.campaign_info ?? 'campaign_info.toml' );
// Compile a specific banner, usually requested by the API
if ( env.banner ) {
const bannerName = env.banner;
const singleEntry = campaigns.getEntryPoints()[ bannerName ];
if ( !singleEntry ) {
throw new Error( `${bannerName} not found in entry point list` );
}
entrypointRules = {
entry: { [ bannerName ]: singleEntry }
};
customizationRules.customizeObject = customizeObject( {
entry: 'replace'
} );
}
// compile specific channel, usually requested on the CLI
if ( env.channel ) {
const channel = env.channel;
const bannerNames = campaigns.getBannerNamesForChannel( channel );
const configuredEntryPonts = campaigns.getEntryPoints();
entrypointRules = {
entry: bannerNames.reduce( ( entries, bannerName ) => {
entries[ bannerName ] = configuredEntryPonts[ bannerName ];
return entries;
}, {} )
};
customizationRules.customizeObject = customizeObject( {
entry: 'replace'
} );
}
return mergeWithCustomize( customizationRules )(
CommonConfig( env ),
{
devtool: false,
mode: 'production',
resolve: {
alias: {
'@environment': path.resolve( __dirname, 'src/environment/prod' )
}
},
plugins: [
new MediaWikiTextWrapper( {
templates: campaigns.getWrapperTemplates( readWrapperTemplate ),
context: {
bannerValues: '{{MediaWiki:WMDE_Fundraising/Campaign_Parameters_2024}}'
},
filePattern: '{B,WMDE}*.js',
campaignConfig: campaigns.getConfigForPages()
} ),
// TODO use wpde url instead
new LoadVueOnWpde( {
// URL where Vue will be loaded from. Should have only the minified runtime version
vueURL: 'https://unpkg.com/vue@3/dist/vue.runtime.global.prod.js',
// Regex matching output names to wrap.
// Should match 'pagename' of WPDE banners in campaigns_info.toml
test: /B.*WPDE_.*\.js/
} ),
// Remove generated license files
// See https://stackoverflow.com/a/72237744/130121
new ( class {
apply( compiler ) {
compiler.hooks.done.tap( 'Remove LICENSE', () => {
rimraf.sync( './dist/*.LICENSE.txt' );
} );
}
} )()
],
externals: [
/**
* In production builds we'll use the Vue class provided by MediaWiki and declare everything imported from
* 'vue' and '@vue/something' an external dependency
*
* To make the Vue class available to the bundled code, you need to wrap it like this:
*
* mw.loader.using( [ 'vue' ], function() { bundled code goes here } );
*
* The MediaWikiTextWrapper webpack plugin (and the template it uses) must take care of the wrapping
*/
function ( { request }, callback ) {
if ( /(^@vue\/|^vue$)/.test( request ) ) {
callback( null, 'Vue' );
return;
}
callback();
}
],
performance: {
// Size limit in Bytes for the generated JS files
maxAssetSize: 310_000,
// Size limit in Bytes for the combined code of entry points
maxEntrypointSize: 310_000
}
},
entrypointRules
);
};