forked from ucfopen/materia-template-widget
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebpack.config.js
More file actions
246 lines (184 loc) · 6.45 KB
/
Copy pathwebpack.config.js
File metadata and controls
246 lines (184 loc) · 6.45 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
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/*
Template Webpack configuration
This config has various options for using the
legacy webpack template to build your widget with
tons of options for customizing
To really understand what's going on, you'll need to look at the source
of the Materia Widget Development Kit:
See https://github.com/ucfopen/Materia-Widget-Dev-Kit/blob/master/webpack-widget.js
BEST PRACTICES FOR PACKAGING WIDGETS
1. JS & CSS: concatenate into one file: all css into player.css, all js into player.js
2. Use CDN's for vendor libraries (see cdnjs)
3. Avoid use of libraries when plain js will do (like jquery)
4. When using ANGULAR.js, use ng-annotate-loader to protect dependency injection from minification
5.".js" files are NOT altered by default. To use babel customize webpack module rules for js files
*/
const path = require('path')
const fs = require('fs')
const srcPath = path.join(__dirname, 'src') + path.sep
const outputPath = path.join(__dirname, 'build')
const widgetWebpack = require('materia-widget-development-kit/webpack-widget')
const rules = widgetWebpack.getDefaultRules()
const entries = widgetWebpack.getDefaultEntries()
const copy = widgetWebpack.getDefaultCopyList()
/*
======= WIDGET CREATOR ======
Normally getLegacyWidgetBuildConfig expects:
* src/creator.coffee
* src/creator.html
* src/creator.scss
==== DIFFERENT IN THIS EXAMPLE ====
We're using coffeescript, but in our case it's angular
and we're relying on a loader to protect shorthand
dependency injection syntax
==== CHANGES NEEDED ====
1. Replace coffeescript loader
*/
const customCoffeeLoader = {
test: /\.coffee$/i,
exclude: /node_modules/,
loader: require('extract-text-webpack-plugin').extract({
use: ['raw-loader', 'ng-annotate-loader', 'babel-loader', 'coffee-loader']
})
}
/*
======= WIDGET PLAYER ======
Normally getLegacyWidgetBuildConfig expects:
* src/player.coffee
* src/player.html
* src/player.scss
==== DIFFERENT IN THIS EXAMPLE ====
We're NOT using coffeescript, instead we're just
concatenating 2 plain javascript files.
==== CHANGES NEEDED ====
1. Overwrite entries for player.js
2. Alter the default to target just our player files
NOTE: #2 is only needed because we don't want a generic *.js rule to apply to scoreScreen
*/
// #1. combine 2 plain js files into player.js
entries['player.js'] = [
`${srcPath}player-module.js`,
`${srcPath}player-controller.js`
]
// #2. Redefine ".test" on loaderDoNothingToJs for just our player files
// Only needed because we don't want a generic *.js rule to apply
// to the ScoreScreen
const customDoNothingToJs = rules.loaderDoNothingToJs
customDoNothingToJs.test = /player-.*\.js$/i
/*
======= SCORE SCREEN ======
getLegacyWidgetBuildConfig doesn't have rules for scoreScreen.
==== DIFFERENT IN THIS EXAMPLE ====
We'll be using React, JSX, Babel, and PLAIN CSS
We'll add entries for the html, a plain css file and a React
==== CHANGES NEEDED ====
1. Add an entry for ScoreScreen.js
2. Add an entry for ScoreScreen.css and html
3. Add a module loader for react and babel*
4. Add an externals config to prevent react
and react-dom from being compiled (at bottom of file)
NOTE, #3 will be loading .js files - make sure this rule
doesn't conflict with other loaders if you're not using
react for all parts of the widget. In this example, you
can see how we changed the loaderDoNothingToJss
to more specifically target the desired files, and
not affect the rules for react.
*/
// #1 React and ES6 via Babel
entries['scoreScreen.js'] = [
`${srcPath}scoreScreen.js`,
]
// #2 CSS & HTML
entries['scoreScreen.css'] = [
`${srcPath}scoreScreen.html`,
`${srcPath}scoreScreen.css`
]
// #3 Custom module loader for react
const customReactLoader = {
test: /scoreScreen.*\.js$/i,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
/*
======= HELPER GUIDES ======
getLegacyWidgetBuildConfig doesn't have any entries for
helper guides by default, but does have some rules set up
to handle them if they are provided
The default rules will expect these entries to be creating
files with specific names - 'guides/player.temp.html' for
the player guide and 'guides/creator.temp.html' for the
creator guide, specifically
==== CHANGES NEEDED ====
1. Add an entry for the player and creator guide (if applicable)
2. If overriding the default rule set, make sure there is a rule
to handle markdown files
==== DIFFERENT IN THIS EXAMPLE ====
Though most widgets will typically have a guide file for both
the player and the creator, this widget uses the default creator
and, accordingly, only has a guide for the player
*/
entries['guides/player.temp.html'] = [
path.join(__dirname, 'src', '_guides', 'player.md')
]
entries['guides/creator.temp.html'] = [
path.join(__dirname, 'src', '_guides', 'creator.md')
]
/*
======= EXTRA FILES ======
To add any extra files that aren't in src/assets, they
need to be added to the copyList
==== DIFFERENT IN THIS EXAMPLE ====
We need extrafile.txt in the "root" directory
==== CHANGES NEEDED ====
1. Append a new file onto the copyList
2. Helper guides typically make use of images - in this case,
we also need to copy the 'src/_guides/assets' directory
*/
const customCopy = copy.concat([
{
from: `${srcPath}extrafile.txt`,
to: outputPath
},
{
from: path.join(__dirname, 'src', '_guides', 'assets'),
to: path.join(outputPath, 'guides', 'assets'),
toType: 'dir'
},
])
/*
======= USE CUSTOM RULES TO BUILD A WEBPACK CONFIG ======
Now we'll send our customizations into getLegacyWidgetBuildConfig
to build a webpack config.
==== CHANGES NEEDED ====
1. Build an array of custom module loader rules
2. Build options object for getLegacyWidgetBuildConfig
3. Add externals for React (used on our score screen)
*/
let customRules = [
customDoNothingToJs, // <--- replaces "rules.loaderDoNothingToJs"
customCoffeeLoader, // <--- replaces "rules.loaderCompileCoffee"
rules.copyImages,
rules.loadHTMLAndReplaceMateriaScripts,
rules.loadAndPrefixCSS,
rules.loadAndPrefixSASS,
rules.loadAndCompileMarkdown,
customReactLoader, // <--- Extra new rule for react
]
// options for the build
let options = {
entries: entries,
moduleRules: customRules,
copyList: customCopy
}
const ourFinalWebpackConfig = widgetWebpack.getLegacyWidgetBuildConfig(options)
// Score Screen #4 (from further up in this file)
// after building, modify externals to make sure
// React and React-Dom are not compiled
// into our source code for the Score Screen
ourFinalWebpackConfig.externals = {
"react": "React",
"react-dom": "ReactDOM"
}
module.exports = ourFinalWebpackConfig