1 | import path from 'path'
|
2 | import preconditions from 'preconditions'
|
3 | import webpack from 'webpack'
|
4 | import WebpackConfigurationFactory from 'webpack/WebpackConfigurationFactory'
|
5 | import WebpackDevServer from 'webpack-dev-server'
|
6 | import url from 'url'
|
7 |
|
8 | class UniversalWebApplicationSetup {
|
9 | static create (options) {
|
10 | return new UniversalWebApplicationSetup(options)
|
11 | }
|
12 |
|
13 | constructor (options) {
|
14 | let pc = preconditions.instance(options)
|
15 | pc.shouldBeDefined('name', 'Please provide the name of the application.')
|
16 | pc.shouldBeDefined('host', 'Please provide the host of the application.')
|
17 | pc.shouldBeDefined('port', 'Please provide the port of the application.')
|
18 | pc.shouldBeDefined('pingPort', 'Please provide the ping port of the application.')
|
19 | pc.shouldBeDefined('rootProjectPath', 'Please provide the rootProjectPath.')
|
20 | pc.shouldBeDefined('rootDeploymentPath', 'Please provide the rootDeploymentPath.')
|
21 | pc.shouldBeDefined('environment', 'Please provide the environment.')
|
22 |
|
23 | console.log('Application is initializing - ', options.name)
|
24 |
|
25 | this._options = options
|
26 |
|
27 | if (this._options.modules == null || typeof this._options.modules === 'undefined') {
|
28 | this._options.modules = []
|
29 | } else {
|
30 | if (!(this._options.modules instanceof Array)) {
|
31 | this._options.modules = []
|
32 | console.warn('[COMPILER] Omitting modules entry. You should put the modules folder in an array.')
|
33 | }
|
34 | }
|
35 |
|
36 | this._applicationName = options.name
|
37 | this._applicationHost = options.host
|
38 |
|
39 | var rootProjectPath = options.rootProjectPath
|
40 | var rootApplicationPath = path.join(options.rootProjectPath, 'applications', options.name)
|
41 |
|
42 | var rootDeploymentPath = options.rootDeploymentPath
|
43 | var rootDeploymentApplicationPath = path.join(options.rootDeploymentPath, 'applications', options.name)
|
44 | let assetHost = options.assetHost !== null && typeof options.assetHost !== 'undefined' ? options.assetHost : options.host
|
45 |
|
46 | let assetPath = options.assetPath || options.artifactPath || '/assets'
|
47 | assetPath += assetPath[assetPath.length - 1] !== '/' ? '/' : ''
|
48 |
|
49 | let artifactPath = options.artifactPath || options.assetPath || '/assets'
|
50 | artifactPath += artifactPath[artifactPath.length - 1] !== '/' ? '/' : ''
|
51 |
|
52 | console.log('==> rootProjectPath: ', rootProjectPath)
|
53 | console.log('==> rootApplicationPath: ', rootApplicationPath)
|
54 | console.log('==> rootDeploymentPath: ', rootDeploymentPath)
|
55 | console.log('==> rootDeploymentApplicationPath: ', rootDeploymentApplicationPath)
|
56 | console.log('==> supportedLocales: ', options.locales)
|
57 | console.log('==> modules: ', options.modules)
|
58 | console.log('==> logger (default - winston): ', options.loggerOptions ? options.loggerOptions.type : 'default')
|
59 |
|
60 | console.log('==> assetHost: ', assetHost)
|
61 | console.log('==> assetPath (default: /assets): ', assetPath)
|
62 | console.log('==> artifactPath (default: /assets): ', artifactPath)
|
63 | console.log('==> useBuildID (default: false): ', !!options.useBuildID)
|
64 |
|
65 | this._rootProjectPath = rootProjectPath
|
66 | this._rootApplicationPath = rootApplicationPath
|
67 | this._rootDeploymentPath = rootDeploymentPath
|
68 | this._rootDeploymentApplicationPath = rootDeploymentApplicationPath
|
69 |
|
70 | let projectConfigurationOptions = {
|
71 | applicationName: options.name,
|
72 | applicationHost: options.host,
|
73 |
|
74 | applicationAssetHost: assetHost,
|
75 | useBuildID: !!options.useBuildID,
|
76 | assetPath: assetPath,
|
77 | artifactPath: artifactPath,
|
78 |
|
79 | rootProjectPath: rootProjectPath,
|
80 | rootApplicationPath: rootApplicationPath,
|
81 | rootDeploymentPath: rootDeploymentPath,
|
82 | rootDeploymentApplicationPath: rootDeploymentApplicationPath,
|
83 | environment: options.environment,
|
84 | locales: options.locales,
|
85 | port: options.port,
|
86 | pingPort: options.pingPort,
|
87 | modules: options.modules,
|
88 | loggerOptions: options.loggerOptions
|
89 | }
|
90 |
|
91 | let webpackConfigurationOptions = {
|
92 | devPort: options.devPort,
|
93 | ...projectConfigurationOptions
|
94 | }
|
95 | console.log('Building webpack configurations, we will put on some commonly used plugin & configuration.')
|
96 | this._webpackConfigurationFactory = new WebpackConfigurationFactory(webpackConfigurationOptions)
|
97 | this._webpackConfiguration = this._webpackConfigurationFactory.createWebpackConfiguration(webpackConfigurationOptions)
|
98 | this._compiler = this._createWebpackCompiler(this._webpackConfiguration)
|
99 | }
|
100 |
|
101 | run () {
|
102 | if (this._options.environment === 'development') {
|
103 | console.log('[COMPILER] Initiating server compilation')
|
104 | let serverConfiguration = this._webpackConfiguration[0]
|
105 | let serverCompiler = this._createWebpackCompiler(serverConfiguration)
|
106 | serverCompiler.watch({
|
107 | aggregateTimeout: 300,
|
108 | poll: true
|
109 | }, (err, stats) => {
|
110 | if (err) console.error(err)
|
111 |
|
112 | console.log(stats.compilation.errors.toString({ colors: true }))
|
113 | console.log(stats.compilation.warnings.toString({ colors: true }))
|
114 | console.log('[COMPILER] Server compilation finished. Watching for server file changes.')
|
115 | })
|
116 |
|
117 | console.log('[COMPILER] Initiating client compilation using webpack-dev-server')
|
118 | let clientConfiguration = this._webpackConfiguration[1]
|
119 | let clientCompiler = this._createWebpackCompiler(clientConfiguration)
|
120 | let clientDevServer = new WebpackDevServer(clientCompiler, {
|
121 | contentBase: path.join(this._rootApplicationPath, 'build'),
|
122 | hot: true,
|
123 | filename: 'main.js',
|
124 | proxy: {
|
125 | '**': 'http://localhost:' + this._options.port
|
126 | },
|
127 | watchOptions: {
|
128 | aggregateTimeout: 300,
|
129 | poll: 1000
|
130 | },
|
131 | stats: {
|
132 | color: true
|
133 | },
|
134 | publicPath: this._options.assetPath || '/assets',
|
135 | disableHostCheck: true
|
136 | })
|
137 | clientDevServer.listen(this._options.devPort, (err) => {
|
138 | if (err) {
|
139 | console.err('[ERROR]: ', err, err.stack)
|
140 | } else {
|
141 | console.log('\n[COMPILER] webpack-dev-server is listening at port ' + this._options.devPort)
|
142 | console.log('[COMPILER] Client compilation finished. Watching for client file changes.')
|
143 | }
|
144 | })
|
145 | } else {
|
146 | console.log('[COMPILER] Initiating compilation.')
|
147 | this._compiler = this._createWebpackCompiler(this._webpackConfiguration)
|
148 | this._compiler.run((err, stats) => {
|
149 | if (err) console.error(err)
|
150 | console.log(stats.toString({ colors: true }))
|
151 | console.log('[COMPILER] Compilation finished.')
|
152 | })
|
153 | }
|
154 | }
|
155 |
|
156 | _createWebpackCompiler (configuration) {
|
157 | let compiler = webpack(configuration)
|
158 | return compiler
|
159 | }
|
160 | }
|
161 |
|
162 | export default UniversalWebApplicationSetup
|