1 | import * as chalk from 'chalk'
|
2 | import * as fs from 'fs'
|
3 | import * as HtmlWebpackPlugin from 'html-webpack-plugin'
|
4 | import * as CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin'
|
5 | import * as InterpolateHtmlPlugin from 'react-dev-utils/InterpolateHtmlPlugin'
|
6 | import * as WatchMissingNodeModulesPlugin from 'react-dev-utils/WatchMissingNodeModulesPlugin'
|
7 | import * as ModuleNotFoundPlugin from 'react-dev-utils/ModuleNotFoundPlugin'
|
8 | import { DefinePlugin, HotModuleReplacementPlugin, IgnorePlugin } from 'webpack'
|
9 | import * as ManifestPlugin from 'webpack-manifest-plugin'
|
10 | import * as ProgressBarPlugin from 'progress-bar-webpack-plugin'
|
11 | import * as forkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'
|
12 |
|
13 |
|
14 | import * as WorkboxWebpackPlugin from 'workbox-webpack-plugin'
|
15 |
|
16 | import * as deepmerge from 'deepmerge'
|
17 | import Berun from '@berun/berun'
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | export const pluginHtml = (
|
23 | berun: Berun,
|
24 | options: { html?: any; title?: string; templateContext?: any } = {}
|
25 | ) => {
|
26 | const ISPRODUCTION = process.env.NODE_ENV === 'production'
|
27 |
|
28 | const htmlPluginArgs = (deepmerge as any)(
|
29 | {
|
30 | inject: true,
|
31 | template: fs.existsSync(berun.options.paths.appHtml)
|
32 | ? berun.options.paths.appHtml
|
33 | : null
|
34 | },
|
35 | (ISPRODUCTION &&
|
36 | ({
|
37 | minify: {
|
38 | removeComments: true,
|
39 | collapseWhitespace: true,
|
40 | removeRedundantAttributes: true,
|
41 | useShortDoctype: true,
|
42 | removeEmptyAttributes: true,
|
43 | removeStyleLinkTypeAttributes: true,
|
44 | keepClosingSlash: true,
|
45 | minifyJS: true,
|
46 | minifyCSS: true,
|
47 | minifyURLs: true
|
48 | }
|
49 | } as any)) ||
|
50 | {},
|
51 | options.html || {}
|
52 | ) as any
|
53 |
|
54 | if (!htmlPluginArgs.template) {
|
55 | delete htmlPluginArgs.template
|
56 | htmlPluginArgs.templateContent = `<!DOCTYPE html>
|
57 | <html>
|
58 | <head>
|
59 | <meta charset='utf-8'>
|
60 | <title>${options.title || 'BeRun App'}</title>
|
61 | <style>*{box-sizing:border-box}body{margin:0;font-family:system-ui,sans-serif}</style>
|
62 | </head>
|
63 | <body>
|
64 | <div id="root"></div>
|
65 | </body>
|
66 | </html>`
|
67 | }
|
68 |
|
69 | berun.webpack
|
70 | .plugin('html')
|
71 | .use(HtmlWebpackPlugin, [htmlPluginArgs])
|
72 | .end()
|
73 | }
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 | export const pluginInterpolateHtml = (berun: Berun, _) => {
|
82 | berun.webpack
|
83 | .plugin('interpolate-html')
|
84 | .use(InterpolateHtmlPlugin, [HtmlWebpackPlugin, berun.options.env.raw])
|
85 | }
|
86 |
|
87 | export const pluginProgressBar = (
|
88 | berun: Berun,
|
89 | opt: { name?: string; color?: string } = {}
|
90 | ) => {
|
91 | const { name = 'berun', color = 'green' } = opt
|
92 |
|
93 | const options = {
|
94 | width: '24',
|
95 | complete: '█',
|
96 | incomplete: chalk.gray('░'),
|
97 | format: [
|
98 | chalk[color](`[${name}] :bar`),
|
99 | chalk[color](':percent'),
|
100 | chalk.gray(':elapseds :msg')
|
101 | ].join(' '),
|
102 | summary: false,
|
103 | customSummary: () => {
|
104 |
|
105 | }
|
106 | }
|
107 |
|
108 | berun.webpack.plugin('progress-bar').use(ProgressBarPlugin, [options])
|
109 | }
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 | export const pluginModuleNotFound = (berun: Berun, _) => {
|
116 | berun.webpack
|
117 | .plugin('modulenotfound')
|
118 | .use(ModuleNotFoundPlugin, [berun.options.paths.appPath])
|
119 | }
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | export const pluginEnv = (berun: Berun, options) => {
|
126 | const processEnv = Object.assign(
|
127 | berun.options.env.stringified['process.env'],
|
128 | options || {}
|
129 | )
|
130 |
|
131 | berun.webpack.plugin('env').use(DefinePlugin, [{ 'process.env': processEnv }])
|
132 | }
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 | export const pluginPackageInfo = (berun: Berun, options) => {
|
139 | const packageJson = require(berun.options.paths.appPackageJson)
|
140 |
|
141 | const PACKAGE = {
|
142 | APP_PATH: JSON.stringify(berun.options.paths.appPath),
|
143 | WORKSPACE: JSON.stringify(berun.options.paths.workspace),
|
144 | PUBLIC_URL: JSON.stringify(berun.options.paths.publicUrl),
|
145 | REMOTE_ORIGIN_URL: JSON.stringify(berun.options.paths.remoteOriginUrl),
|
146 | TITLE: JSON.stringify(packageJson.name || 'BeRun App'),
|
147 | VERSION: JSON.stringify(packageJson.version),
|
148 | DIRECTORIES: JSON.stringify(packageJson.directories || {})
|
149 | }
|
150 |
|
151 | const processEnv = Object.assign(
|
152 | PACKAGE,
|
153 | berun.options.env.stringified['process.env'],
|
154 | options || {}
|
155 | )
|
156 |
|
157 | berun.webpack.plugin('env').use(DefinePlugin, [
|
158 | {
|
159 | 'process.env': processEnv
|
160 | }
|
161 | ])
|
162 | }
|
163 |
|
164 |
|
165 |
|
166 |
|
167 | export const pluginHot = (berun: Berun, _) => {
|
168 | berun.webpack.plugin('hot').use(HotModuleReplacementPlugin)
|
169 | }
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 | export const pluginCaseSensitivePaths = (berun: Berun, _) => {
|
176 | berun.webpack.plugin('case-sensitive-paths').use(CaseSensitivePathsPlugin)
|
177 | }
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 | export const pluginWatchMissingNodeModules = (berun: Berun, _) => {
|
185 | berun.webpack
|
186 | .plugin('watch-missing-node-modules')
|
187 | .use(WatchMissingNodeModulesPlugin, [berun.options.paths.appNodeModules])
|
188 | }
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 | export const pluginMoment = (berun: Berun, _) => {
|
196 | berun.webpack.plugin('moment').use(IgnorePlugin, [/^\.\/locale$/, /moment$/])
|
197 | }
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 | export const pluginManifest = (berun: Berun, _) => {
|
205 | berun.webpack.plugin('manifest').use(ManifestPlugin, [
|
206 | {
|
207 | fileName: 'asset-manifest.json',
|
208 | publicPath: berun.options.paths.publicPath
|
209 | }
|
210 | ])
|
211 | }
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 | export const pluginWorkbox = (berun: Berun, _) => {
|
218 | berun.webpack.plugin('workbox').use(WorkboxWebpackPlugin.GenerateSW, [
|
219 | {
|
220 | clientsClaim: true,
|
221 | exclude: [/\.map$/, /asset-manifest\.json$/],
|
222 | importWorkboxFrom: 'cdn',
|
223 | navigateFallback: `${berun.options.paths.publicUrl}/index.html`,
|
224 | navigateFallbackBlacklist: [
|
225 |
|
226 | new RegExp('^/_'),
|
227 |
|
228 |
|
229 | new RegExp('/[^/]+\\.[^/]+$')
|
230 | ]
|
231 | }
|
232 | ])
|
233 | }
|
234 |
|
235 |
|
236 |
|
237 |
|
238 | export const pluginForkTsChecker = (berun: Berun, _) => {
|
239 | berun.webpack
|
240 | .plugin('fork-ts-checker')
|
241 | .use(forkTsCheckerWebpackPlugin as any, [
|
242 | {
|
243 | async: false,
|
244 | tsconfig: berun.options.paths.appTSConfig,
|
245 | eslint: false
|
246 | }
|
247 | ])
|
248 | }
|