UNPKG

4.59 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
6
7const Asset = require('../Asset');
8
9const commandExists = require('command-exists');
10
11const localRequire = require('../utils/localRequire');
12
13const _require = require('terser'),
14 minify = _require.minify;
15
16const path = require('path');
17
18const spawn = require('cross-spawn');
19
20class ElmAsset extends Asset {
21 constructor(name, options) {
22 super(name, options);
23 this.type = 'js';
24 }
25
26 parse() {
27 var _this = this;
28
29 return (0, _asyncToGenerator2.default)(function* () {
30 let options = {
31 cwd: path.dirname(_this.name)
32 }; // If elm is not installed globally, install it locally.
33
34 try {
35 yield commandExists('elm');
36 } catch (err) {
37 yield localRequire('elm', _this.name);
38 options.pathToElm = path.join(path.dirname(require.resolve('elm')), 'bin', 'elm');
39 }
40
41 _this.elm = yield localRequire('node-elm-compiler', _this.name); // Ensure that an elm.json file exists, and initialize one if not.
42
43 let elmConfig = yield _this.getConfig(['elm.json'], {
44 load: false
45 });
46
47 if (!elmConfig) {
48 yield _this.createElmConfig(options); // Ensure we are watching elm.json for changes
49
50 yield _this.getConfig(['elm.json'], {
51 load: false
52 });
53 }
54
55 options.debug = !_this.options.production;
56
57 if (_this.options.minify) {
58 options.optimize = true;
59 }
60
61 _this.elmOpts = options;
62 })();
63 }
64
65 collectDependencies() {
66 var _this2 = this;
67
68 return (0, _asyncToGenerator2.default)(function* () {
69 let dependencies = yield _this2.elm.findAllDependencies(_this2.name);
70 var _iteratorNormalCompletion = true;
71 var _didIteratorError = false;
72 var _iteratorError = undefined;
73
74 try {
75 for (var _iterator = dependencies[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
76 let dependency = _step.value;
77
78 _this2.addDependency(dependency, {
79 includedInParent: true
80 });
81 }
82 } catch (err) {
83 _didIteratorError = true;
84 _iteratorError = err;
85 } finally {
86 try {
87 if (!_iteratorNormalCompletion && _iterator.return != null) {
88 _iterator.return();
89 }
90 } finally {
91 if (_didIteratorError) {
92 throw _iteratorError;
93 }
94 }
95 }
96 })();
97 }
98
99 createElmConfig(options) {
100 return (0, _asyncToGenerator2.default)(function* () {
101 let cp = spawn(options.pathToElm || 'elm', ['init']);
102 cp.stdin.write('y\n');
103 return new Promise((resolve, reject) => {
104 cp.on('error', reject);
105 cp.on('close', function (code) {
106 if (code !== 0) {
107 return reject(new Error('elm init failed.'));
108 }
109
110 return resolve();
111 });
112 });
113 })();
114 }
115
116 generate() {
117 var _this3 = this;
118
119 return (0, _asyncToGenerator2.default)(function* () {
120 let compiled = yield _this3.elm.compileToString(_this3.name, _this3.elmOpts);
121 _this3.contents = compiled.toString();
122
123 if (_this3.options.hmr) {
124 let _ref = yield localRequire('elm-hot', _this3.name),
125 inject = _ref.inject;
126
127 _this3.contents = inject(_this3.contents);
128 }
129
130 let output = _this3.contents;
131
132 if (_this3.options.minify) {
133 output = pack(output);
134 }
135
136 return {
137 [_this3.type]: output
138 }; // Recommended minification
139 // Based on:
140 // - http://elm-lang.org/0.19.0/optimize
141
142 function pack(source) {
143 let options = {
144 compress: {
145 keep_fargs: false,
146 passes: 2,
147 pure_funcs: ['F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'],
148 pure_getters: true,
149 unsafe: true,
150 unsafe_comps: true
151 },
152 mangle: true,
153 rename: false
154 };
155 let result = minify(source, options);
156
157 if (result.error) {
158 throw result.error;
159 }
160
161 return result.code;
162 }
163 })();
164 }
165
166 generateErrorMessage(err) {
167 // The generated stack is not useful, but other code may
168 // expect it and try to print it, so make it an empty string.
169 err.stack = '';
170 return err;
171 }
172
173}
174
175module.exports = ElmAsset;
\No newline at end of file