@@ -6,6 +6,8 @@ import HtmlWebpackExcludeAssetsPlugin from "html-webpack-exclude-assets-plugin"
6
6
import MiniCssExtractPlugin from "mini-css-extract-plugin"
7
7
// TODO: swap back when https://github.com/geowarin/friendly-errors-webpack-plugin/pull/86 lands
8
8
import FriendlyErrorsPlugin from "@pieh/friendly-errors-webpack-plugin"
9
+ import CopyPlugin from "copy-webpack-plugin"
10
+ import HtmlWebpackTagsPlugin from "html-webpack-tags-plugin"
9
11
10
12
// Deep mapping function for plain objects and arrays. Allows any value,
11
13
// including an object or array, to be transformed.
@@ -47,19 +49,6 @@ function replaceRule(value) {
47
49
return null
48
50
}
49
51
50
- // Manually swap `style-loader` for `MiniCssExtractPlugin.loader`.
51
- // `style-loader` is only used in development, and doesn't allow us to pass
52
- // the `styles` entry css path to Netlify CMS.
53
- if (
54
- typeof value . loader === `string` &&
55
- value . loader . includes ( `style-loader` )
56
- ) {
57
- return {
58
- ...value ,
59
- loader : MiniCssExtractPlugin . loader ,
60
- }
61
- }
62
-
63
52
return value
64
53
}
65
54
@@ -90,7 +79,7 @@ exports.onCreateDevServer = ({ app, store }, { publicPath = `admin` }) => {
90
79
}
91
80
92
81
exports . onCreateWebpackConfig = (
93
- { store, stage, getConfig, plugins, pathPrefix, loaders, rules } ,
82
+ { store, stage, getConfig, plugins, pathPrefix, loaders, rules, actions } ,
94
83
{
95
84
modulePath,
96
85
customizeWebpackConfig,
@@ -108,13 +97,45 @@ exports.onCreateWebpackConfig = (
108
97
const gatsbyConfig = getConfig ( )
109
98
const { program } = store . getState ( )
110
99
const publicPathClean = trim ( publicPath , `/` )
100
+
101
+ const externals = [
102
+ {
103
+ name : `react` ,
104
+ global : `React` ,
105
+ assetDir : `umd` ,
106
+ assetName : `react.production.min.js` ,
107
+ } ,
108
+ {
109
+ name : `react-dom` ,
110
+ global : `ReactDOM` ,
111
+ assetDir : `umd` ,
112
+ assetName : `react-dom.production.min.js` ,
113
+ } ,
114
+ {
115
+ name : `netlify-cms-app` ,
116
+ global : `NetlifyCmsApp` ,
117
+ assetDir : `dist` ,
118
+ assetName : `netlify-cms-app.js` ,
119
+ sourceMap : `netlify-cms-app.js.map` ,
120
+ } ,
121
+ ]
122
+
123
+ if ( enableIdentityWidget ) {
124
+ externals . unshift ( {
125
+ name : `netlify-identity-widget` ,
126
+ global : `netlifyIdentity` ,
127
+ assetDir : `build` ,
128
+ assetName : `netlify-identity-widget.js` ,
129
+ sourceMap : `netlify-identity-widget.js.map` ,
130
+ } )
131
+ }
132
+
111
133
const config = {
112
134
...gatsbyConfig ,
113
135
entry : {
114
136
cms : [
115
- manualInit && `${ __dirname } /cms-manual-init.js` ,
116
- `${ __dirname } /cms.js` ,
117
- enableIdentityWidget && `${ __dirname } /cms-identity.js` ,
137
+ path . join ( __dirname , `cms.js` ) ,
138
+ enableIdentityWidget && path . join ( __dirname , `cms-identity.js` ) ,
118
139
]
119
140
. concat ( modulePath )
120
141
. filter ( p => p ) ,
@@ -153,9 +174,10 @@ exports.onCreateWebpackConfig = (
153
174
154
175
// Use a simple filename with no hash so we can access from source by
155
176
// path.
156
- new MiniCssExtractPlugin ( {
157
- filename : `[name].css` ,
158
- } ) ,
177
+ stage !== `develop` &&
178
+ new MiniCssExtractPlugin ( {
179
+ filename : `[name].css` ,
180
+ } ) ,
159
181
160
182
// Auto generate CMS index.html page.
161
183
new HtmlWebpackPlugin ( {
@@ -178,6 +200,34 @@ exports.onCreateWebpackConfig = (
178
200
__PATH__PREFIX__ : pathPrefix ,
179
201
CMS_PUBLIC_PATH : JSON . stringify ( publicPath ) ,
180
202
} ) ,
203
+
204
+ new CopyPlugin (
205
+ [ ] . concat . apply (
206
+ [ ] ,
207
+ externals . map ( ( { name, assetName, sourceMap, assetDir } ) =>
208
+ [
209
+ {
210
+ from : path . join ( `node_modules` , name , assetDir , assetName ) ,
211
+ to : assetName ,
212
+ } ,
213
+ sourceMap && {
214
+ from : path . join ( `node_modules` , name , assetDir , sourceMap ) ,
215
+ to : sourceMap ,
216
+ } ,
217
+ ] . filter ( item => item )
218
+ )
219
+ )
220
+ ) ,
221
+
222
+ new HtmlWebpackTagsPlugin ( {
223
+ tags : externals . map ( ( { assetName } ) => assetName ) ,
224
+ append : false ,
225
+ } ) ,
226
+
227
+ new webpack . DefinePlugin ( {
228
+ CMS_MANUAL_INIT : JSON . stringify ( manualInit ) ,
229
+ PRODUCTION : JSON . stringify ( stage !== `develop` ) ,
230
+ } ) ,
181
231
] . filter ( p => p ) ,
182
232
183
233
// Remove common chunks style optimizations from Gatsby's default
@@ -189,6 +239,11 @@ exports.onCreateWebpackConfig = (
189
239
minimizer : stage === `develop` ? [ ] : gatsbyConfig . optimization . minimizer ,
190
240
} ,
191
241
devtool : stage === `develop` ? `cheap-module-source-map` : `source-map` ,
242
+ externals : externals . map ( ( { name, global } ) => {
243
+ return {
244
+ [ name ] : global ,
245
+ }
246
+ } ) ,
192
247
}
193
248
194
249
if ( customizeWebpackConfig ) {
@@ -203,6 +258,33 @@ exports.onCreateWebpackConfig = (
203
258
} )
204
259
}
205
260
261
+ actions . setWebpackConfig ( {
262
+ // force code splitting for netlify-identity-widget
263
+ optimization :
264
+ stage === `develop`
265
+ ? { }
266
+ : {
267
+ splitChunks : {
268
+ cacheGroups : {
269
+ "netlify-identity-widget" : {
270
+ test : / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] ( n e t l i f y - i d e n t i t y - w i d g e t ) [ \\ / ] / ,
271
+ name : `netlify-identity-widget` ,
272
+ chunks : `all` ,
273
+ enforce : true ,
274
+ } ,
275
+ } ,
276
+ } ,
277
+ } ,
278
+ // ignore netlify-identity-widget when not enabled
279
+ plugins : enableIdentityWidget
280
+ ? [ ]
281
+ : [
282
+ new webpack . IgnorePlugin ( {
283
+ resourceRegExp : / ^ n e t l i f y - i d e n t i t y - w i d g e t $ / ,
284
+ } ) ,
285
+ ] ,
286
+ } )
287
+
206
288
return new Promise ( ( resolve , reject ) => {
207
289
if ( stage === `develop` ) {
208
290
webpack ( config ) . watch ( { } , ( ) => { } )
0 commit comments