1 | import path from 'path'
|
2 | import fs from 'fs'
|
3 |
|
4 | import require_hacker from 'require-hacker'
|
5 |
|
6 | import { is_object, exists, starts_with } from './helpers'
|
7 |
|
8 |
|
9 |
|
10 | export function default_webpack_assets()
|
11 | {
|
12 | const webpack_assets =
|
13 | {
|
14 | javascript: {},
|
15 | styles: {},
|
16 | assets: {}
|
17 | }
|
18 |
|
19 | return webpack_assets
|
20 | }
|
21 |
|
22 |
|
23 | export function normalize_options(options)
|
24 | {
|
25 |
|
26 | for (let key of Object.keys(options))
|
27 | {
|
28 | switch (key)
|
29 | {
|
30 | case 'assets':
|
31 | if (!is_object(options[key]))
|
32 | {
|
33 | throw new Error(`"${key}" configuration parameter must be ` + `an object`)
|
34 | }
|
35 | break
|
36 |
|
37 | case 'debug':
|
38 | if (typeof options[key] !== 'boolean')
|
39 | {
|
40 | throw new Error(`"${key}" configuration parameter must be ` + `a boolean`)
|
41 | }
|
42 | break
|
43 |
|
44 | case 'verbose':
|
45 | if (typeof options[key] !== 'boolean')
|
46 | {
|
47 | throw new Error(`"${key}" configuration parameter must be ` + `a boolean`)
|
48 | }
|
49 |
|
50 | console.log('[webpack-isomorphic-tools] WARNING: `verbose` option is now called `verbosity`')
|
51 | if (options.verbose)
|
52 | {
|
53 | options.verbosity = verbosity_levels.webpack_stats_for_each_build
|
54 | }
|
55 | delete options.verbose
|
56 | break
|
57 |
|
58 | case 'verbosity':
|
59 | if (typeof options[key] !== 'string')
|
60 | {
|
61 | throw new Error(`"${key}" configuration parameter must be ` + `a string`)
|
62 | }
|
63 | if (Object.keys(verbosity_levels).map(key => verbosity_levels[key]).indexOf(options[key]) < 0)
|
64 | {
|
65 | throw new Error(`Unknown "verbosity" passed: ${options[key]}`)
|
66 | }
|
67 | break
|
68 |
|
69 | case 'port':
|
70 | if (typeof options[key] !== 'number')
|
71 | {
|
72 | throw new Error(`"${key}" configuration parameter must be ` + `a number`)
|
73 | }
|
74 | break
|
75 |
|
76 | case 'webpack_assets_file_path':
|
77 | case 'webpack_stats_file_path':
|
78 | if (typeof options[key] !== 'string')
|
79 | {
|
80 | throw new Error(`"${key}" configuration parameter must be ` + `a string`)
|
81 | }
|
82 | break
|
83 |
|
84 | case 'alias':
|
85 | if (!is_object(options[key]))
|
86 | {
|
87 | throw new Error(`"${key}" configuration parameter must be ` + `an object`)
|
88 | }
|
89 | break
|
90 |
|
91 | case 'modules_directories':
|
92 | if (!Array.isArray(options[key]))
|
93 | {
|
94 | throw new Error(`"${key}" configuration parameter must be ` + `an array`)
|
95 | }
|
96 | break
|
97 |
|
98 | case 'require_context':
|
99 | if (typeof options[key] !== 'boolean')
|
100 | {
|
101 | throw new Error(`"${key}" configuration parameter must be ` + `a boolean`)
|
102 | }
|
103 |
|
104 | console.log('[webpack-isomorphic-tools] WARNING: `require_context` option is now called `patch_require`')
|
105 | delete options.require_context
|
106 | options.patch_require = true
|
107 | break
|
108 |
|
109 | case 'patch_require':
|
110 | if (typeof options[key] !== 'boolean')
|
111 | {
|
112 | throw new Error(`"${key}" configuration parameter must be ` + `a boolean`)
|
113 | }
|
114 | break
|
115 |
|
116 | default:
|
117 | throw new Error(`Unknown configuration parameter "${key}"`)
|
118 | }
|
119 | }
|
120 |
|
121 |
|
122 | if (!options.assets)
|
123 | {
|
124 |
|
125 | throw new Error('You must specify "assets" parameter in webpack-isomorphic-tools configuration')
|
126 | }
|
127 |
|
128 |
|
129 | options.webpack_assets_file_path = options.webpack_assets_file_path || 'webpack-assets.json'
|
130 |
|
131 |
|
132 | options.webpack_stats_file_path = options.webpack_stats_file_path || 'webpack-stats.json'
|
133 |
|
134 |
|
135 | if (options.alias)
|
136 | {
|
137 | for (let key of Object.keys(options.alias))
|
138 | {
|
139 | if (typeof options.alias[key] !== 'string')
|
140 | {
|
141 | throw new Error(`Invalid alias for "${key}": "${options.alias[key]}"`)
|
142 | }
|
143 | }
|
144 | }
|
145 |
|
146 |
|
147 | for (let asset_type of Object.keys(options.assets))
|
148 | {
|
149 | const description = options.assets[asset_type]
|
150 |
|
151 |
|
152 | if (description.extension)
|
153 | {
|
154 |
|
155 | if (Array.isArray(description.extension))
|
156 | {
|
157 | throw new Error(`Use "extensions" key instead of "extension" for specifying an array of file extensions for assets of type "${asset_type}"`)
|
158 | }
|
159 |
|
160 |
|
161 | if (typeof description.extension !== 'string')
|
162 | {
|
163 | throw new Error(`"extension" value must be a string for assets of type "${asset_type}"`)
|
164 | }
|
165 |
|
166 |
|
167 | description.extensions = [description.extension]
|
168 | delete description.extension
|
169 | }
|
170 |
|
171 |
|
172 | if (!description.extensions)
|
173 | {
|
174 | throw new Error(`You must specify file extensions for assets of type "${asset_type}"`)
|
175 | }
|
176 |
|
177 |
|
178 | for (let key of Object.keys(description))
|
179 | {
|
180 | switch (key)
|
181 | {
|
182 | case 'extensions':
|
183 | break
|
184 |
|
185 | case 'exclude':
|
186 | case 'include':
|
187 | if (!Array.isArray(description[key]))
|
188 | {
|
189 | throw new Error(`"${key}" must be an array for asset type "${asset_type}"`)
|
190 | }
|
191 | for (let clusion of description[key])
|
192 | {
|
193 | if (typeof clusion !== 'string'
|
194 | && !(clusion instanceof RegExp)
|
195 | && typeof clusion !== 'function')
|
196 | {
|
197 | throw new Error(`Unsupported object type for exclusion/inclusion "${clusion}" for asset type "${asset_type}"`)
|
198 | }
|
199 | }
|
200 | break
|
201 |
|
202 | case 'filter':
|
203 | case 'parser':
|
204 | case 'path':
|
205 | if (typeof description[key] !== 'function')
|
206 | {
|
207 | throw new Error(`"${key}" must be a function for asset type "${asset_type}"`)
|
208 | }
|
209 | break
|
210 |
|
211 | case 'regular_expression':
|
212 | if (!(description[key] instanceof RegExp))
|
213 | {
|
214 | throw new Error(`"${key}" must be a regular expression for asset type "${asset_type}"`)
|
215 | }
|
216 | break
|
217 |
|
218 | default:
|
219 | throw new Error(`Unknown property "${key}" for asset type "${asset_type}"`)
|
220 | }
|
221 | }
|
222 | }
|
223 | }
|
224 |
|
225 |
|
226 |
|
227 | export function alias_hook(path, module, project_path, aliases, log)
|
228 | {
|
229 |
|
230 | const aliased_path = alias(path, aliases)
|
231 |
|
232 |
|
233 | if (!aliased_path)
|
234 | {
|
235 | return
|
236 | }
|
237 |
|
238 |
|
239 | log.debug(`require("${path}") was called and an alias was found, so aliasing to module path "${aliased_path}"`)
|
240 |
|
241 |
|
242 | const global_path = require_hacker.resolve(aliased_path, module)
|
243 | log.debug(` resolved the path for the aliased module to ${global_path}`)
|
244 |
|
245 | return global_path
|
246 |
|
247 |
|
248 |
|
249 |
|
250 |
|
251 | }
|
252 |
|
253 |
|
254 | function alias(path, aliases)
|
255 | {
|
256 |
|
257 | if (starts_with(path, '.') || starts_with(path, '/'))
|
258 | {
|
259 | return
|
260 | }
|
261 |
|
262 |
|
263 | const slash_index = path.indexOf('/')
|
264 | const module_name = slash_index >= 0 ? path.substring(0, slash_index) : path
|
265 | const rest = slash_index >= 0 ? path.substring(slash_index) : ''
|
266 |
|
267 |
|
268 | const alias = aliases[module_name]
|
269 |
|
270 |
|
271 | if (alias)
|
272 | {
|
273 | return alias + rest
|
274 | }
|
275 | }
|
276 |
|
277 |
|
278 | export function normalize_asset_path(global_asset_path, project_path)
|
279 | {
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 | let asset_path = path.relative(project_path, global_asset_path)
|
292 |
|
293 |
|
294 |
|
295 |
|
296 | asset_path = uniform_path(asset_path)
|
297 |
|
298 | return asset_path
|
299 | }
|
300 |
|
301 |
|
302 |
|
303 |
|
304 | export function uniform_path(asset_path)
|
305 | {
|
306 |
|
307 | asset_path = asset_path.replace(/\\/g, '/')
|
308 |
|
309 |
|
310 | if (asset_path.indexOf('.') !== 0)
|
311 | {
|
312 | asset_path = './' + asset_path
|
313 | }
|
314 |
|
315 | return asset_path
|
316 | }
|
317 |
|
318 | export const verbosity_levels =
|
319 | {
|
320 | no_webpack_stats : 'no webpack stats',
|
321 | webpack_stats_for_each_build : 'webpack stats for each build'
|
322 | } |
\ | No newline at end of file |