1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 | const fs = require('fs');
|
6 | const path = require('path');
|
7 | const findup = require('findup');
|
8 | const semverUtils = require('semver-utils');
|
9 | const prettyjson = require('prettyjson');
|
10 | const merge = require('lodash/merge');
|
11 | const isFinite = require('lodash/isFinite');
|
12 | const isUndefined = require('lodash/isUndefined');
|
13 | const utils = require('./utils/utils');
|
14 | const consts = require('./consts');
|
15 | const DvhbWebpackError = require('./utils/error');
|
16 |
|
17 | const CONFIG_FILENAME = 'dvhb.config.js';
|
18 | const DEFAULT_CONFIG = {
|
19 | title: 'Dvhb Webpack Starter kit',
|
20 | sourceDir: 'src',
|
21 | assetsDir: null,
|
22 | distDir: 'dist',
|
23 | viewsDir: 'src/views',
|
24 | template: 'src/index.html',
|
25 | serverHost: 'localhost',
|
26 | serverPort: 3000,
|
27 | verbose: false,
|
28 | extendWebpackConfig: null
|
29 | };
|
30 | const DEPENDENCIES = [
|
31 | {
|
32 | package: 'babel-core',
|
33 | name: 'Babel',
|
34 | from: 6,
|
35 | to: 6,
|
36 | },
|
37 | {
|
38 | package: 'webpack',
|
39 | name: 'Webpack',
|
40 | from: 1,
|
41 | to: 2,
|
42 | },
|
43 | ];
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | function getConfig(options) {
|
52 | options = options || {};
|
53 |
|
54 | let configFilepath;
|
55 | let config;
|
56 |
|
57 |
|
58 | configFilepath = findConfig(options.config);
|
59 | config = require(configFilepath);
|
60 |
|
61 | validateConfig(config);
|
62 |
|
63 | const configDir = configFilepath ? path.dirname(configFilepath) : process.cwd();
|
64 |
|
65 | validateDependencies(configDir);
|
66 |
|
67 | let assetsDir = null;
|
68 | if (typeof config.assetsDir === 'string') {
|
69 | assetsDir = path.resolve(configDir, config.assetsDir);
|
70 | if (!utils.isDirectoryExists(assetsDir)) {
|
71 | throw new DvhbWebpackError('DvhbWebpack: "assetsDir" directory not found: ' + assetsDir);
|
72 | }
|
73 | }
|
74 | if (Array.isArray(config.assetsDir)) {
|
75 | assetsDir = [];
|
76 | config.assetsDir.forEach(function (dir) {
|
77 | assetsDir.push(path.resolve(configDir, dir));
|
78 | });
|
79 | }
|
80 |
|
81 | config = merge({}, DEFAULT_CONFIG, config);
|
82 | config = merge({}, config, {
|
83 | env: options.env || 'development',
|
84 | verbose: !!options.verbose,
|
85 | sourceDir: path.resolve(configDir, config.sourceDir),
|
86 | distDir: path.resolve(configDir, config.distDir),
|
87 | viewsDir: path.resolve(configDir, config.viewsDir),
|
88 | assetsDir: assetsDir,
|
89 | configDir,
|
90 | });
|
91 |
|
92 | if (config.template) {
|
93 | config.template = path.resolve(configDir, config.template)
|
94 | }
|
95 |
|
96 | if (config.verbose) {
|
97 | console.log();
|
98 | console.log('Using config file:', configFilepath);
|
99 | console.log(prettyjson.render(config));
|
100 | console.log();
|
101 | }
|
102 |
|
103 | return config;
|
104 | }
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 | function findConfig(file) {
|
113 | if (file) {
|
114 |
|
115 |
|
116 | const configFilepath = file[0] === '/' ? file : path.join(process.cwd(), file);
|
117 | if (!fs.existsSync(configFilepath)) {
|
118 | throw new DvhbWebpackError('DvhbWebpack config not found: ' + configFilepath + '.');
|
119 | }
|
120 |
|
121 | return configFilepath;
|
122 | }
|
123 |
|
124 |
|
125 |
|
126 | let configDir;
|
127 | try {
|
128 | configDir = findup.sync(__dirname, CONFIG_FILENAME);
|
129 | }
|
130 | catch (exception) {
|
131 | throw new DvhbWebpackError('DvhbWebpack config not found: ' + CONFIG_FILENAME + '.');
|
132 | }
|
133 |
|
134 | return path.join(configDir, CONFIG_FILENAME);
|
135 | }
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 | function validateConfig(config) {
|
143 | if (config.extendWebpackConfig && typeof config.extendWebpackConfig !== 'function') {
|
144 | throw new DvhbWebpackError('DvhbWebpack: "extendWebpackConfig" option must be a function.');
|
145 | }
|
146 | }
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 | function validateDependencies(configDir) {
|
154 | const packageJsonPath = path.join(findup.sync(configDir, 'package.json'), 'package.json');
|
155 | const packageJson = require(packageJsonPath);
|
156 | DEPENDENCIES.forEach(validateDependency.bind(null, packageJson));
|
157 | }
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 | function validateDependency(packageJson, dependency) {
|
166 | const version = findDependency(dependency.package, packageJson);
|
167 | if (!version) {
|
168 | return;
|
169 | }
|
170 |
|
171 | let major;
|
172 | try {
|
173 | major = semverUtils.parseRange(version)[0].major;
|
174 | }
|
175 | catch (exception) {
|
176 | console.log('DvhbWebpack: cannot parse ' + dependency.name + ' version which is "' + version + '".');
|
177 | console.log('DvhbWebpack might not work properly. Please report this issue at ' + consts.BUGS_URL);
|
178 | console.log();
|
179 | }
|
180 |
|
181 | if (major < dependency.from) {
|
182 | throw new DvhbWebpackError('DvhbWebpack: ' + dependency.name + ' ' + dependency.from + ' is required, ' +
|
183 | 'you are using version ' + major + '.');
|
184 | }
|
185 | else if (major > dependency.to) {
|
186 | console.log('DvhbWebpack: ' + dependency.name + ' is supported up to version ' + dependency.to + ', ' +
|
187 | 'you are using version ' + major + '.');
|
188 | console.log('DvhbWebpack might not work properly, report bugs at ' + consts.BUGS_URL);
|
189 | console.log();
|
190 | }
|
191 | }
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 | function findDependency(name, packageJson) {
|
201 | if (packageJson.dependencies && packageJson.dependencies[name]) {
|
202 | return packageJson.dependencies[name];
|
203 | }
|
204 | if (packageJson.devDependencies && packageJson.devDependencies[name]) {
|
205 | return packageJson.devDependencies[name];
|
206 | }
|
207 | return null;
|
208 | }
|
209 |
|
210 | module.exports = getConfig;
|