1 | const
|
2 | path = require('path'),
|
3 | fs = require('fs'),
|
4 | glob = require('glob'),
|
5 | pug = require('pug'),
|
6 | stylus = require('stylus'),
|
7 | nib = require('nib'),
|
8 | autoprefixer = require('autoprefixer-stylus'),
|
9 | {rollup} = require('rollup'),
|
10 | rollupPluginPug = require('rollup-plugin-pug'),
|
11 | rollupPluginResolve = require('rollup-plugin-node-resolve'),
|
12 | rollupPluginReplace = require('rollup-plugin-replace'),
|
13 | rollupPluginCommonjs = require('rollup-plugin-commonjs'),
|
14 | rollupPluginGlobImport = require('rollup-plugin-glob-import'),
|
15 | rollupPluginAlias = require('rollup-plugin-alias'),
|
16 | rollupPluginBabel = require('rollup-plugin-babel'),
|
17 | sgUtil = require('./util');
|
18 |
|
19 | class AppBuilder {
|
20 |
|
21 | constructor(conf, CollectorStore) {
|
22 |
|
23 | this.conf = conf;
|
24 | this.CollectorStore = CollectorStore;
|
25 | this.name = this.conf.get('package.name');
|
26 | this.viewerDest = this.conf.get('viewerDest');
|
27 | this.source = path.resolve(__dirname, '..', 'app');
|
28 | this.sections = [];
|
29 |
|
30 | this.generateViewerPages = this.generateViewerPages.bind(this);
|
31 | this.generateViewerStyles = this.generateViewerStyles.bind(this);
|
32 | this.rollupViewerScripts = this.rollupViewerScripts.bind(this);
|
33 | this.getViewerPagesLocals = this.getViewerPagesLocals.bind(this);
|
34 | this.onEnd = this.onEnd.bind(this);
|
35 | }
|
36 |
|
37 | renderCollected() {
|
38 | if (!this.watcher) {
|
39 | this.CollectorStore.getFiles()
|
40 | .forEach(async (file) => {
|
41 | if (!file.exclude) {
|
42 | await file.render;
|
43 | }
|
44 | });
|
45 | }
|
46 |
|
47 | return this;
|
48 | }
|
49 |
|
50 | saveCollectedData() {
|
51 | if (!this.watcher) {
|
52 | const {viewerDest, CollectorStore: {getCollectedData}} = this;
|
53 | sgUtil.writeJsonFile(path.join(viewerDest, 'structure.json'), getCollectedData());
|
54 | }
|
55 | }
|
56 |
|
57 | getViewerPagesLocals() {
|
58 | return {
|
59 | description: this.conf.get('package.description', 'No description'),
|
60 | version: this.conf.get('version', this.conf.get('package.version') || 'dev')
|
61 | };
|
62 | }
|
63 |
|
64 | onEnd(message) {
|
65 | return (error) => {
|
66 | if (error) {
|
67 | throw error;
|
68 | }
|
69 | sgUtil.log(`[✓] ${this.name} ${message}`, 'info');
|
70 | };
|
71 | }
|
72 |
|
73 | async generateViewerPages() {
|
74 | const
|
75 | {source, viewerDest, getViewerPagesLocals} = this,
|
76 | onEnd = this.onEnd('viewer html generated.'),
|
77 | templateFile = path.join(source, 'templates', 'viewer', 'index.pug'),
|
78 | renderOptions = Object.assign({
|
79 | pretty: true,
|
80 | cache: false
|
81 | },
|
82 | getViewerPagesLocals());
|
83 |
|
84 | sgUtil.writeFile(path.join(viewerDest, 'index.html'), pug.renderFile(templateFile, renderOptions), onEnd);
|
85 | }
|
86 |
|
87 | async generateViewerStyles() {
|
88 |
|
89 | const
|
90 | {source, viewerDest} = this,
|
91 | onEnd = this.onEnd('viewer css generated.'),
|
92 | stylusStr = glob.sync(`${source}/style/**/!(_)*.styl`)
|
93 | .map((file) => fs.readFileSync(file, 'utf8'))
|
94 | .join('\n');
|
95 |
|
96 | stylus(stylusStr)
|
97 | .set('include css', true)
|
98 | .set('prefix', 'dsc-')
|
99 | .use(nib())
|
100 | .use(autoprefixer({
|
101 | browsers: ['> 5%', 'last 1 versions'],
|
102 | cascade: false
|
103 | }))
|
104 | .include(path.join(source, 'style'))
|
105 | .import('_reset')
|
106 | .import('_mixins')
|
107 | .import('_variables')
|
108 | .render((err, css) => {
|
109 | if (err) {
|
110 | onEnd(err);
|
111 | }
|
112 | else {
|
113 | sgUtil.writeFile(path.join(viewerDest, 'css', 'app.css'), css, onEnd);
|
114 | }
|
115 | });
|
116 | }
|
117 |
|
118 | async rollupViewerScripts() {
|
119 | const
|
120 | {source, viewerDest} = this,
|
121 | destFile = path.join(viewerDest, 'scripts', 'app.js');
|
122 |
|
123 | sgUtil.createPath(destFile);
|
124 |
|
125 | try {
|
126 | const bundle = await rollup({
|
127 | input: path.join(source, 'scripts', 'index.js'),
|
128 | plugins: [
|
129 | rollupPluginGlobImport({
|
130 | rename(name, id) {
|
131 | if (path.basename(id) !== 'index.js') {
|
132 | return null;
|
133 | }
|
134 | return path.basename(path.dirname(id));
|
135 | }
|
136 | }),
|
137 | rollupPluginAlias({
|
138 | vue: 'node_modules/vue/dist/vue.esm.js'
|
139 | }),
|
140 | rollupPluginResolve({
|
141 | jsnext: true,
|
142 | main: true,
|
143 | module: true
|
144 | }),
|
145 | rollupPluginPug(),
|
146 | rollupPluginReplace({
|
147 | 'process.env.NODE_ENV': JSON.stringify('development')
|
148 | }),
|
149 | rollupPluginCommonjs(),
|
150 | rollupPluginBabel()
|
151 | ]
|
152 | });
|
153 |
|
154 | await bundle.write({
|
155 | file: destFile,
|
156 | format: 'iife',
|
157 | sourcemap: false
|
158 | });
|
159 | }
|
160 | catch (error) {
|
161 | throw error;
|
162 | }
|
163 |
|
164 | this.onEnd('viewer js bundle generated.');
|
165 | }
|
166 | }
|
167 |
|
168 | module.exports = AppBuilder;
|