From 563297e251fce249af87f6ae8756ebbdce1a572b Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Thu, 30 Aug 2018 12:46:36 +0000 Subject: [PATCH 01/30] Implemented change so that any asset can force a reload in HMR. --- src/Asset.js | 1 + src/HMRServer.js | 4 ++-- src/assets/HTMLAsset.js | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Asset.js b/src/Asset.js index e37da38422f..9b256822803 100644 --- a/src/Asset.js +++ b/src/Asset.js @@ -27,6 +27,7 @@ class Asset { this.options = options; this.encoding = 'utf8'; this.type = path.extname(this.name).slice(1); + this.forceReload = false; this.processed = false; this.contents = options.rendition ? options.rendition.value : null; diff --git a/src/HMRServer.js b/src/HMRServer.js index ed62cba146d..bb41696a9c4 100644 --- a/src/HMRServer.js +++ b/src/HMRServer.js @@ -62,8 +62,8 @@ class HMRServer { }); } - const containsHtmlAsset = assets.some(asset => asset.type === 'html'); - if (containsHtmlAsset) { + const shouldReload = assets.some(asset => asset.forceReload); + if (shouldReload) { this.broadcast({ type: 'reload' }); diff --git a/src/assets/HTMLAsset.js b/src/assets/HTMLAsset.js index 244391bd312..eb479644123 100644 --- a/src/assets/HTMLAsset.js +++ b/src/assets/HTMLAsset.js @@ -85,6 +85,7 @@ class HTMLAsset extends Asset { super(name, options); this.type = 'html'; this.isAstDirty = false; + this.forceReload = true; } async parse(code) { From 7f2d72e8d8ee593b3e05b9808316a293aa605a6b Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Thu, 30 Aug 2018 19:15:36 +0000 Subject: [PATCH 02/30] Added asset for Elm. --- package.json | 3 ++ src/assets/ElmAsset.js | 70 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/assets/ElmAsset.js diff --git a/package.json b/package.json index f69b075120a..49432f73ccf 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,9 @@ "codecov": "^3.0.0", "coffeescript": "^2.0.3", "cross-env": "^5.1.1", + "elm": "^0.19.0-bugfix2", "eslint": "^4.13.0", + "find-elm-dependencies": "^2.0.0", "glslify-bundle": "^5.0.0", "glslify-deps": "^1.3.0", "graphql": "^0.11.7", @@ -97,6 +99,7 @@ "mocha": "^5.1.1", "ncp": "^2.0.0", "nib": "^1.1.2", + "node-elm-compiler": "^5.0.1", "nyc": "^11.1.0", "postcss-modules": "^1.1.0", "posthtml-extend": "^0.2.1", diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js new file mode 100644 index 00000000000..b502f64ca72 --- /dev/null +++ b/src/assets/ElmAsset.js @@ -0,0 +1,70 @@ +const process = require('process'); +const Asset = require('../Asset'); +const localRequire = require('../utils/localRequire'); +const {minify} = require('terser'); + +class ElmAsset extends Asset { + constructor(name, options) { + super(name, options); + this.type = 'js'; + } + + async collectDependencies() { + const { findAllDependencies } = await localRequire('find-elm-dependencies', this.name); + const dependencies = await findAllDependencies(this.name); + + dependencies.forEach(dependency => { + this.addDependency(dependency, { includedInParent: true }); + }); + } + + async parse() { + const elm = await localRequire('node-elm-compiler', this.name); + + const options = { + cwd: process.cwd() + }; + + if (this.options.minify) { + options.optimize = true; + } + + const compiled = await elm.compileToString(this.name, options); + this.contents = compiled.toString(); + } + + async generate() { + let output = this.contents; + + if (this.options.minify) { + output = mangle(compress(output)); + } + + return { + [this.type]: output + }; + + function compress(source) { + const options = { + compress: { + keep_fargs: false, + pure_funcs: 'F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9'.split(','), + pure_getters: true, + unsafe: true, + unsafe_comps: true + } + }; + + const { code } = minify(source, options); + return code; + } + + function mangle(source) { + const { code } = minify(source, { mangle: true }); + return code; + } + } + +} + +module.exports = ElmAsset; From 0386b89cda26d3cbf3701a179e0c08b67e6c8c0d Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Thu, 30 Aug 2018 19:20:13 +0000 Subject: [PATCH 03/30] Registered extension. --- src/Parser.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Parser.js b/src/Parser.js index 68ff9f811e3..e53503cb5a3 100644 --- a/src/Parser.js +++ b/src/Parser.js @@ -17,6 +17,7 @@ class Parser { this.registerExtension('ts', './assets/TypeScriptAsset'); this.registerExtension('tsx', './assets/TypeScriptAsset'); this.registerExtension('coffee', './assets/CoffeeScriptAsset'); + this.registerExtension('elm', './assets/ElmAsset'); this.registerExtension('vue', './assets/VueAsset'); this.registerExtension('json', './assets/JSONAsset'); this.registerExtension('json5', './assets/JSONAsset'); From acca76de8d67b84b37418c7dea34e1a4f9708e52 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Thu, 30 Aug 2018 19:26:56 +0000 Subject: [PATCH 04/30] Set Elm assets to force a page reload. --- src/assets/ElmAsset.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index b502f64ca72..eee5414ab91 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -7,6 +7,7 @@ class ElmAsset extends Asset { constructor(name, options) { super(name, options); this.type = 'js'; + this.forceReload = true; } async collectDependencies() { From fad0f8cf1c2f79a74384368011a134172edd127a Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Thu, 30 Aug 2018 19:47:39 +0000 Subject: [PATCH 05/30] Added comment referencing optimal Terser configuration. --- src/assets/ElmAsset.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index eee5414ab91..e7102cc5187 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -45,6 +45,9 @@ class ElmAsset extends Asset { [this.type]: output }; + // Optimal Terser Configuration + // Based on: + // - http://elm-lang.org/0.19.0/optimize function compress(source) { const options = { compress: { From 2062007574c4bf9871dcb994e87d10faaf573a10 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Thu, 30 Aug 2018 20:21:27 +0000 Subject: [PATCH 06/30] Added integration test for Elm. --- test/elm.js | 21 ++++++++++++++ test/integration/elm/elm.json | 24 ++++++++++++++++ test/integration/elm/index.js | 5 ++++ test/integration/elm/src/Main.elm | 47 +++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 test/elm.js create mode 100644 test/integration/elm/elm.json create mode 100644 test/integration/elm/index.js create mode 100644 test/integration/elm/src/Main.elm diff --git a/test/elm.js b/test/elm.js new file mode 100644 index 00000000000..b37e040b525 --- /dev/null +++ b/test/elm.js @@ -0,0 +1,21 @@ +const assert = require('assert'); +const {bundle, assertBundleTree, run} = require('./utils'); +const process = require('process'); + +describe('elm', function() { + before(function() { + process.chdir(__dirname + '/integration/elm'); + }); + + it('should produce a basic elm bundle', async function() { + let b = await bundle(__dirname + '/integration/elm/index.js'); + + await assertBundleTree(b, { + type: 'js', + assets: ['Main.elm', 'index.js'] + }); + + let output = await run(b); + assert.equal(typeof output().Elm.Main.init, 'function'); + }); +}); diff --git a/test/integration/elm/elm.json b/test/integration/elm/elm.json new file mode 100644 index 00000000000..dd41cae2a31 --- /dev/null +++ b/test/integration/elm/elm.json @@ -0,0 +1,24 @@ +{ + "type": "application", + "source-directories": [ + "src" + ], + "elm-version": "0.19.0", + "dependencies": { + "direct": { + "elm/browser": "1.0.0", + "elm/core": "1.0.0", + "elm/html": "1.0.0" + }, + "indirect": { + "elm/json": "1.0.0", + "elm/time": "1.0.0", + "elm/url": "1.0.0", + "elm/virtual-dom": "1.0.0" + } + }, + "test-dependencies": { + "direct": {}, + "indirect": {} + } +} \ No newline at end of file diff --git a/test/integration/elm/index.js b/test/integration/elm/index.js new file mode 100644 index 00000000000..61906ed5a66 --- /dev/null +++ b/test/integration/elm/index.js @@ -0,0 +1,5 @@ +var local = require('./src/Main.elm'); + +module.exports = function () { + return local; +}; \ No newline at end of file diff --git a/test/integration/elm/src/Main.elm b/test/integration/elm/src/Main.elm new file mode 100644 index 00000000000..3c9a587a70d --- /dev/null +++ b/test/integration/elm/src/Main.elm @@ -0,0 +1,47 @@ +module Main exposing (main) + +import Browser +import Html exposing (Html, button, div, text) +import Html.Events exposing (onClick) + + +type alias Model = + { count : Int } + + +initialModel : Model +initialModel = + { count = 0 } + + +type Msg + = Increment + | Decrement + + +update : Msg -> Model -> Model +update msg model = + case msg of + Increment -> + { model | count = model.count + 1 } + + Decrement -> + { model | count = model.count - 1 } + + +view : Model -> Html Msg +view model = + div [] + [ button [ onClick Increment ] [ text "+1" ] + , div [] [ text <| String.fromInt model.count ] + , button [ onClick Decrement ] [ text "-1" ] + ] + + +main : Program () Model Msg +main = + Browser.sandbox + { init = initialModel + , view = view + , update = update + } From ae839b3033d96d829984b03ed0dc2cc1c443e478 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Thu, 30 Aug 2018 20:24:02 +0000 Subject: [PATCH 07/30] Excluded package folder. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fc1b4628edd..24ce2d076d5 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ coverage .cache dist lib +!test/**/elm-stuff !test/**/node_modules .vscode/ .idea/ From 52e5aac257a902157cda8479188e1e06efb88037 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Thu, 30 Aug 2018 21:02:48 +0000 Subject: [PATCH 08/30] Fixed test. --- .gitignore | 2 +- src/assets/ElmAsset.js | 4 ++++ test/elm.js | 7 +------ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 24ce2d076d5..ee0ab92de5e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,11 +8,11 @@ coverage .cache dist lib -!test/**/elm-stuff !test/**/node_modules .vscode/ .idea/ *.min.js +test/integration/**/elm-stuff test/integration/**/target test/integration/**/Cargo.lock test/**/node_modules diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index e7102cc5187..1aaac7d38de 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -26,6 +26,10 @@ class ElmAsset extends Asset { cwd: process.cwd() }; + if (process.env.NODE_ENV === 'test') { + options.cwd += '/test/integration/elm'; + } + if (this.options.minify) { options.optimize = true; } diff --git a/test/elm.js b/test/elm.js index b37e040b525..cde169f43bb 100644 --- a/test/elm.js +++ b/test/elm.js @@ -1,15 +1,10 @@ const assert = require('assert'); const {bundle, assertBundleTree, run} = require('./utils'); -const process = require('process'); describe('elm', function() { - before(function() { - process.chdir(__dirname + '/integration/elm'); - }); - it('should produce a basic elm bundle', async function() { let b = await bundle(__dirname + '/integration/elm/index.js'); - + await assertBundleTree(b, { type: 'js', assets: ['Main.elm', 'index.js'] From 7e444122794c0526accd6fb053771931cc1b06c9 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 01:01:25 +0000 Subject: [PATCH 09/30] Fixed path for integration test. --- src/assets/ElmAsset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index 1aaac7d38de..b5afebbe3f4 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -27,7 +27,7 @@ class ElmAsset extends Asset { }; if (process.env.NODE_ENV === 'test') { - options.cwd += '/test/integration/elm'; + options.cwd = this.options.rootDir; } if (this.options.minify) { From 1c1c9375c2ed02da531787211342a6c7129638cf Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 12:23:41 +0000 Subject: [PATCH 10/30] Fixed linting issues. --- src/assets/ElmAsset.js | 61 +++++++++++++++++++++++++++--------------- test/elm.js | 2 +- test/graphql.js | 2 -- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index b5afebbe3f4..b8c8e794c6b 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -9,70 +9,89 @@ class ElmAsset extends Asset { this.type = 'js'; this.forceReload = true; } - + async collectDependencies() { - const { findAllDependencies } = await localRequire('find-elm-dependencies', this.name); + const {findAllDependencies} = await localRequire( + 'find-elm-dependencies', + this.name + ); const dependencies = await findAllDependencies(this.name); - + dependencies.forEach(dependency => { - this.addDependency(dependency, { includedInParent: true }); + this.addDependency(dependency, {includedInParent: true}); }); } - + async parse() { const elm = await localRequire('node-elm-compiler', this.name); - + const options = { cwd: process.cwd() }; - + if (process.env.NODE_ENV === 'test') { - options.cwd = this.options.rootDir; + options.cwd = this.options.rootDir; } - + if (this.options.minify) { options.optimize = true; } - + const compiled = await elm.compileToString(this.name, options); this.contents = compiled.toString(); } async generate() { let output = this.contents; - + if (this.options.minify) { output = mangle(compress(output)); } - + return { [this.type]: output }; - - // Optimal Terser Configuration + + // Optimal Terser Configuration // Based on: - // - http://elm-lang.org/0.19.0/optimize + // - http://elm-lang.org/0.19.0/optimize function compress(source) { const options = { compress: { keep_fargs: false, - pure_funcs: 'F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9'.split(','), + pure_funcs: [ + 'F2', + 'F3', + 'F4', + 'F5', + 'F6', + 'F7', + 'F8', + 'F9', + 'A2', + 'A3', + 'A4', + 'A5', + 'A6', + 'A7', + 'A8', + 'A9' + ], pure_getters: true, unsafe: true, unsafe_comps: true } }; - - const { code } = minify(source, options); + + const {code} = minify(source, options); return code; } - + function mangle(source) { - const { code } = minify(source, { mangle: true }); + const {code} = minify(source, {mangle: true}); return code; } } - } module.exports = ElmAsset; diff --git a/test/elm.js b/test/elm.js index cde169f43bb..463667fb291 100644 --- a/test/elm.js +++ b/test/elm.js @@ -4,7 +4,7 @@ const {bundle, assertBundleTree, run} = require('./utils'); describe('elm', function() { it('should produce a basic elm bundle', async function() { let b = await bundle(__dirname + '/integration/elm/index.js'); - + await assertBundleTree(b, { type: 'js', assets: ['Main.elm', 'index.js'] diff --git a/test/graphql.js b/test/graphql.js index acab8202112..4c890f7b1dc 100644 --- a/test/graphql.js +++ b/test/graphql.js @@ -32,7 +32,6 @@ describe('graphql', function() { firstName lastName } - `.definitions ); }); @@ -73,7 +72,6 @@ describe('graphql', function() { address email } - `.definitions ); }); From a2127eac48175a022f2fa791685524b2b3d7b16e Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 12:56:34 +0000 Subject: [PATCH 11/30] Added test for production mode. --- src/assets/ElmAsset.js | 19 +++++++++---------- test/elm.js | 20 +++++++++++++++++++- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index b8c8e794c6b..ef0a9eb0a67 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -45,18 +45,18 @@ class ElmAsset extends Asset { let output = this.contents; if (this.options.minify) { - output = mangle(compress(output)); + output = pack(output); } return { [this.type]: output }; - // Optimal Terser Configuration + // Optimized two-pass minification // Based on: // - http://elm-lang.org/0.19.0/optimize - function compress(source) { - const options = { + function pack(source) { + const firstPass = { compress: { keep_fargs: false, pure_funcs: [ @@ -83,13 +83,12 @@ class ElmAsset extends Asset { } }; - const {code} = minify(source, options); - return code; - } + const secondPass = {mangle: true}; + + const compressed = minify(source, firstPass); + const mangled = minify(compressed.code, secondPass); - function mangle(source) { - const {code} = minify(source, {mangle: true}); - return code; + return mangled.code; } } } diff --git a/test/elm.js b/test/elm.js index 463667fb291..a25568a0a37 100644 --- a/test/elm.js +++ b/test/elm.js @@ -1,8 +1,9 @@ const assert = require('assert'); +const fs = require('fs'); const {bundle, assertBundleTree, run} = require('./utils'); describe('elm', function() { - it('should produce a basic elm bundle', async function() { + it('should produce a basic Elm bundle', async function() { let b = await bundle(__dirname + '/integration/elm/index.js'); await assertBundleTree(b, { @@ -13,4 +14,21 @@ describe('elm', function() { let output = await run(b); assert.equal(typeof output().Elm.Main.init, 'function'); }); + + it('should minify Elm in production mode', async function() { + let b = await bundle(__dirname + '/integration/elm/index.js', { + production: true + }); + + await assertBundleTree(b, { + type: 'js', + assets: ['Main.elm', 'index.js'] + }); + + let output = await run(b); + assert.equal(typeof output().Elm.Main.init, 'function'); + + let js = await fs.readFile(__dirname + '/dist/index.js', 'utf8'); + assert(!js.includes('init')); + }); }); From a6ec42090b2f89c12d33fd846893928c2bb00e0a Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 13:01:52 +0000 Subject: [PATCH 12/30] Fixed module path. --- test/elm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/elm.js b/test/elm.js index a25568a0a37..89b5b1cd91d 100644 --- a/test/elm.js +++ b/test/elm.js @@ -1,5 +1,5 @@ const assert = require('assert'); -const fs = require('fs'); +const fs = require('../src/utils/fs'); const {bundle, assertBundleTree, run} = require('./utils'); describe('elm', function() { From 6844a1b4b478def9a87f04401940df8a02ea92ff Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 13:08:39 +0000 Subject: [PATCH 13/30] Removed assertion. --- test/elm.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/elm.js b/test/elm.js index 89b5b1cd91d..bd1cbccd83d 100644 --- a/test/elm.js +++ b/test/elm.js @@ -20,11 +20,6 @@ describe('elm', function() { production: true }); - await assertBundleTree(b, { - type: 'js', - assets: ['Main.elm', 'index.js'] - }); - let output = await run(b); assert.equal(typeof output().Elm.Main.init, 'function'); From 51d07adf57ea5a3e7e36929578e04a1d0656b771 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 13:21:21 +0000 Subject: [PATCH 14/30] Fixed assertion for minification test. --- test/elm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/elm.js b/test/elm.js index bd1cbccd83d..245ac4ca46c 100644 --- a/test/elm.js +++ b/test/elm.js @@ -24,6 +24,6 @@ describe('elm', function() { assert.equal(typeof output().Elm.Main.init, 'function'); let js = await fs.readFile(__dirname + '/dist/index.js', 'utf8'); - assert(!js.includes('init')); + assert(!js.includes('elm$core')); }); }); From 09903459a217a68c866929cdb607f229363d20b6 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 13:31:57 +0000 Subject: [PATCH 15/30] Updated comment. --- src/assets/ElmAsset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index ef0a9eb0a67..0d85ea33c02 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -52,7 +52,7 @@ class ElmAsset extends Asset { [this.type]: output }; - // Optimized two-pass minification + // Recommended two-pass minification // Based on: // - http://elm-lang.org/0.19.0/optimize function pack(source) { From c1a8e8eb8e6037d89ab16f9f04bec4edf33ab04c Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 14:21:56 +0000 Subject: [PATCH 16/30] Removed formatting in GraphQL test. --- test/graphql.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/graphql.js b/test/graphql.js index 4c890f7b1dc..acab8202112 100644 --- a/test/graphql.js +++ b/test/graphql.js @@ -32,6 +32,7 @@ describe('graphql', function() { firstName lastName } + `.definitions ); }); @@ -72,6 +73,7 @@ describe('graphql', function() { address email } + `.definitions ); }); From ba651ceeca31868b676ed1e68da45d81c5f97691 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 14:50:35 +0000 Subject: [PATCH 17/30] Updated yarn.lock. --- yarn.lock | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 169 insertions(+), 7 deletions(-) diff --git a/yarn.lock b/yarn.lock index 55691853d2d..15173e7f341 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1424,11 +1424,33 @@ binary-extensions@^1.0.0: version "1.12.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" +"binary@>= 0.3.0 < 1": + version "0.3.0" + resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + dependencies: + buffers "~0.1.1" + chainsaw "~0.1.0" + bindings@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11" -bluebird@^3.0.5, bluebird@^3.1.1: +binwrap@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/binwrap/-/binwrap-0.1.4.tgz#ca1f7870302212518fa24b07726f9c50a15c7559" + dependencies: + request "^2.81.0" + request-promise "^4.2.0" + tar "^2.2.1" + unzip "^0.1.11" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^3.0.5, bluebird@^3.1.1, bluebird@^3.5.0: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -1622,6 +1644,10 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffers@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1723,6 +1749,12 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" +chainsaw@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + dependencies: + traverse ">=0.3.0 <0.4" + chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -2126,6 +2158,13 @@ cross-env@^5.1.1: cross-spawn "^5.1.0" is-windows "^1.0.0" +cross-spawn@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.0.tgz#8254774ab4786b8c5b3cf4dfba66ce563932c252" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + cross-spawn@^4: version "4.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" @@ -2663,6 +2702,12 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +elm@^0.19.0-bugfix2: + version "0.19.0-bugfix2" + resolved "https://registry.yarnpkg.com/elm/-/elm-0.19.0-bugfix2.tgz#b2b7ad4dbeb89edf997759330b3694f419f9f1b3" + dependencies: + binwrap "0.1.4" + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -3046,6 +3091,13 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-elm-dependencies@2.0.0, find-elm-dependencies@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-elm-dependencies/-/find-elm-dependencies-2.0.0.tgz#435aa05a6544a0ecf54c5d1ac85cc1ca1044e4e4" + dependencies: + firstline "1.2.0" + lodash "4.17.10" + find-parent-dir@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" @@ -3070,6 +3122,10 @@ findup@^0.1.5: colors "~0.6.0-1" commander "~2.1.0" +firstline@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/firstline/-/firstline-1.2.0.tgz#c9f4886e7f7fbf0afc12d71941dce06b192aea05" + flat-cache@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" @@ -3147,6 +3203,24 @@ fsevents@^1.2.2: nan "^2.9.2" node-pre-gyp "^0.10.0" +"fstream@>= 0.1.30 < 1": + version "0.1.31" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-0.1.31.tgz#7337f058fbbbbefa8c9f561a28cab0849202c988" + dependencies: + graceful-fs "~3.0.2" + inherits "~2.0.0" + mkdirp "0.5" + rimraf "2" + +fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + fswatcher-child@^1.0.5: version "1.1.1" resolved "https://registry.yarnpkg.com/fswatcher-child/-/fswatcher-child-1.1.1.tgz#264dd95f9c4b5f8615327d7d7567884591846b9b" @@ -3382,6 +3456,12 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +graceful-fs@~3.0.2: + version "3.0.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" + dependencies: + natives "^1.1.0" + grapheme-breaker@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/grapheme-breaker/-/grapheme-breaker-0.3.2.tgz#5b9e6b78c3832452d2ba2bb1cb830f96276410ac" @@ -3683,7 +3763,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -4732,7 +4812,7 @@ lodash.values@~2.3.0: dependencies: lodash.keys "~2.3.0" -lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: +lodash@4.17.10, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" @@ -4814,6 +4894,13 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +"match-stream@>= 0.0.2 < 1": + version "0.0.2" + resolved "https://registry.yarnpkg.com/match-stream/-/match-stream-0.0.2.tgz#99eb050093b34dffade421b9ac0b410a9cfa17cf" + dependencies: + buffers "~0.1.1" + readable-stream "~1.0.0" + math-expression-evaluator@^1.2.14: version "1.2.17" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" @@ -4972,7 +5059,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -5030,6 +5117,10 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +natives@^1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.4.tgz#2f0f224fc9a7dd53407c7667c84cf8dbe773de58" + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -5066,6 +5157,15 @@ nise@^1.2.0: path-to-regexp "^1.7.0" text-encoding "^0.6.4" +node-elm-compiler@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/node-elm-compiler/-/node-elm-compiler-5.0.1.tgz#d62094ee72d6aad616ebaa71397b6cfac90381f6" + dependencies: + cross-spawn "4.0.0" + find-elm-dependencies "2.0.0" + lodash "4.17.10" + temp "^0.8.3" + node-forge@^0.7.1: version "0.7.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" @@ -5434,6 +5534,10 @@ output-file-sync@^2.0.0: is-plain-obj "^1.1.0" mkdirp "^0.5.1" +"over@>= 0.0.5 < 1": + version "0.0.5" + resolved "https://registry.yarnpkg.com/over/-/over-0.0.5.tgz#f29852e70fd7e25f360e013a8ec44c82aedb5708" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -6341,6 +6445,15 @@ pug@^2.0.3: pug-runtime "^2.0.4" pug-strip-comments "^1.0.3" +"pullstream@>= 0.4.1 < 1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/pullstream/-/pullstream-0.4.1.tgz#d6fb3bf5aed697e831150eb1002c25a3f8ae1314" + dependencies: + over ">= 0.0.5 < 1" + readable-stream "~1.0.31" + setimmediate ">= 1.0.2 < 2" + slice-stream ">= 1.0.0 < 2" + punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" @@ -6432,7 +6545,7 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -"readable-stream@>=1.0.33-1 <1.1.0-0": +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.0, readable-stream@~1.0.31: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" dependencies: @@ -6610,6 +6723,15 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.0" tough-cookie ">=2.3.3" +request-promise@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.2.tgz#d1ea46d654a6ee4f8ee6a4fea1018c22911904b4" + dependencies: + bluebird "^3.5.0" + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + request@^2.81.0, request@^2.83.0: version "2.85.0" resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" @@ -6716,12 +6838,16 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@^2.2.8, rimraf@^2.6.1, rimraf@^2.6.2: +rimraf@2, rimraf@^2.2.8, rimraf@^2.6.1, rimraf@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: glob "^7.0.5" +rimraf@~2.2.6: + version "2.2.8" + resolved "http://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -6857,7 +6983,7 @@ set-value@^2.0.0: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.4: +"setimmediate@>= 1.0.1 < 2", "setimmediate@>= 1.0.2 < 2", setimmediate@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -6930,6 +7056,12 @@ slice-ansi@1.0.0: dependencies: is-fullwidth-code-point "^2.0.0" +"slice-stream@>= 1.0.0 < 2": + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-stream/-/slice-stream-1.0.0.tgz#5b33bd66f013b1a7f86460b03d463dec39ad3ea0" + dependencies: + readable-stream "~1.0.31" + slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -7342,6 +7474,14 @@ table@4.0.2: slice-ansi "1.0.0" string-width "^2.1.1" +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + tar@^4: version "4.4.6" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" @@ -7354,6 +7494,13 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" +temp@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" + dependencies: + os-tmpdir "^1.0.0" + rimraf "~2.2.6" + terser@^3.7.3: version "3.7.3" resolved "https://registry.yarnpkg.com/terser/-/terser-3.7.3.tgz#e2b6a38f989e4fe46630d4858d184b76ce34883a" @@ -7475,6 +7622,10 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -7595,6 +7746,17 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +unzip@^0.1.11: + version "0.1.11" + resolved "https://registry.yarnpkg.com/unzip/-/unzip-0.1.11.tgz#89749c63b058d7d90d619f86b98aa1535d3b97f0" + dependencies: + binary ">= 0.3.0 < 1" + fstream ">= 0.1.30 < 1" + match-stream ">= 0.0.2 < 1" + pullstream ">= 0.4.1 < 1" + readable-stream "~1.0.31" + setimmediate ">= 1.0.1 < 2" + upath@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" From ecfd64a9a0bcb91dadb14d9ea1fd806e2d81b737 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 15:37:00 +0000 Subject: [PATCH 18/30] Switched minification to a single pass. --- src/assets/ElmAsset.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index 0d85ea33c02..3ac953852f1 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -52,11 +52,11 @@ class ElmAsset extends Asset { [this.type]: output }; - // Recommended two-pass minification + // Recommended minification // Based on: // - http://elm-lang.org/0.19.0/optimize function pack(source) { - const firstPass = { + const options = { compress: { keep_fargs: false, pure_funcs: [ @@ -77,18 +77,15 @@ class ElmAsset extends Asset { 'A8', 'A9' ], + mangle: true, pure_getters: true, unsafe: true, unsafe_comps: true } }; - const secondPass = {mangle: true}; - - const compressed = minify(source, firstPass); - const mangled = minify(compressed.code, secondPass); - - return mangled.code; + const {code} = minify(source, options); + return code; } } } From dcd7d42ad64a237669755b6498b8569f81da893b Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 15:44:45 +0000 Subject: [PATCH 19/30] Fixed minification options. --- src/assets/ElmAsset.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index 3ac953852f1..05110e67f20 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -77,11 +77,11 @@ class ElmAsset extends Asset { 'A8', 'A9' ], - mangle: true, pure_getters: true, unsafe: true, unsafe_comps: true - } + }, + mangle: true }; const {code} = minify(source, options); From c013178dbf7a733be3c688f057a14f11754a8193 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 15:59:07 +0000 Subject: [PATCH 20/30] Disabled rename pass. --- src/assets/ElmAsset.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index 05110e67f20..91ccfef54d8 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -81,7 +81,8 @@ class ElmAsset extends Asset { unsafe: true, unsafe_comps: true }, - mangle: true + mangle: true, + rename: false }; const {code} = minify(source, options); From 40262843919db60299265d73aeb4d259c2ad89f2 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 16:07:24 +0000 Subject: [PATCH 21/30] Added error handling for minification. --- src/assets/ElmAsset.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index 91ccfef54d8..bb3154ce3ed 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -85,8 +85,13 @@ class ElmAsset extends Asset { rename: false }; - const {code} = minify(source, options); - return code; + const result = minify(source, options); + + if (result.error) { + throw new Error(result.error); + } + + return result.code; } } } From 646dc93ad26ce4165c8ec4bed52ae51f5b506182 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 16:09:58 +0000 Subject: [PATCH 22/30] Adjusted error throw. --- src/assets/ElmAsset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index bb3154ce3ed..af066ac6a0f 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -88,7 +88,7 @@ class ElmAsset extends Asset { const result = minify(source, options); if (result.error) { - throw new Error(result.error); + throw result.error; } return result.code; From 28a5823ebde3f85e74a32cafe71a69b8cac713d0 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 16:19:02 +0000 Subject: [PATCH 23/30] Set compress to perform 2 passes. --- src/assets/ElmAsset.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index af066ac6a0f..7f7422004e5 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -59,6 +59,7 @@ class ElmAsset extends Asset { const options = { compress: { keep_fargs: false, + passes: 2, pure_funcs: [ 'F2', 'F3', From 03bd9868577ca1a11dadafdce9bd75949e43999c Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Fri, 31 Aug 2018 16:26:38 +0000 Subject: [PATCH 24/30] Fixed linting issue. --- src/assets/ElmAsset.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index 7f7422004e5..c16e483caf5 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -87,11 +87,11 @@ class ElmAsset extends Asset { }; const result = minify(source, options); - + if (result.error) { throw result.error; } - + return result.code; } } From c0766dacfdeef8b004457016bb1ed224be5e95b3 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Sun, 2 Sep 2018 12:27:13 +0000 Subject: [PATCH 25/30] Renamed flag to be better describe its purpose. --- src/Asset.js | 2 +- src/HMRServer.js | 2 +- src/assets/ElmAsset.js | 2 +- src/assets/HTMLAsset.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Asset.js b/src/Asset.js index 9b256822803..c04735af6bf 100644 --- a/src/Asset.js +++ b/src/Asset.js @@ -27,7 +27,7 @@ class Asset { this.options = options; this.encoding = 'utf8'; this.type = path.extname(this.name).slice(1); - this.forceReload = false; + this.hmrPageReload = false; this.processed = false; this.contents = options.rendition ? options.rendition.value : null; diff --git a/src/HMRServer.js b/src/HMRServer.js index bb41696a9c4..45176385e90 100644 --- a/src/HMRServer.js +++ b/src/HMRServer.js @@ -62,7 +62,7 @@ class HMRServer { }); } - const shouldReload = assets.some(asset => asset.forceReload); + const shouldReload = assets.some(asset => asset.hmrPageReload); if (shouldReload) { this.broadcast({ type: 'reload' diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index c16e483caf5..a5995522e51 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -7,7 +7,7 @@ class ElmAsset extends Asset { constructor(name, options) { super(name, options); this.type = 'js'; - this.forceReload = true; + this.hmrPageReload = true; } async collectDependencies() { diff --git a/src/assets/HTMLAsset.js b/src/assets/HTMLAsset.js index eb479644123..0c655180b88 100644 --- a/src/assets/HTMLAsset.js +++ b/src/assets/HTMLAsset.js @@ -85,7 +85,7 @@ class HTMLAsset extends Asset { super(name, options); this.type = 'html'; this.isAstDirty = false; - this.forceReload = true; + this.hmrPageReload = true; } async parse(code) { From 9cb6d709b12b34bd1dd4f9267f3229b666ea2e32 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Sun, 2 Sep 2018 13:23:23 +0000 Subject: [PATCH 26/30] Added Elm package file to asset dependencies. --- src/assets/ElmAsset.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index a5995522e51..37798c3869f 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -1,5 +1,7 @@ +const path = require('path'); const process = require('process'); const Asset = require('../Asset'); +const fs = require('../utils/fs'); const localRequire = require('../utils/localRequire'); const {minify} = require('terser'); @@ -16,10 +18,33 @@ class ElmAsset extends Asset { this.name ); const dependencies = await findAllDependencies(this.name); + const packageFile = await findPackageFile(path.dirname(this.name)); + + if (packageFile) { + dependencies.push(packageFile); + } dependencies.forEach(dependency => { this.addDependency(dependency, {includedInParent: true}); }); + + // Recursively search for a package file + async function findPackageFile(baseDir) { + const parsedPath = path.parse(baseDir); + const elmPackagePath = path.join(parsedPath.dir, 'elm.json'); + + if (await fs.exists(elmPackagePath)) { + return elmPackagePath; + } + + // Stop if we've reached the file system root + if (parsedPath.root === parsedPath.dir) { + return undefined; + } + + // Continue searching + return findPackageFile(path.dirname(baseDir)); + } } async parse() { From 100ffda984d76cdf0e853102d9549de284f981b1 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Sun, 2 Sep 2018 13:28:06 +0000 Subject: [PATCH 27/30] Added a missing await. --- src/assets/ElmAsset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index 37798c3869f..11292ab58ef 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -43,7 +43,7 @@ class ElmAsset extends Asset { } // Continue searching - return findPackageFile(path.dirname(baseDir)); + return await findPackageFile(path.dirname(baseDir)); } } From a588ea8fd0aa739b566f0d7acdd7992322df0657 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Sun, 2 Sep 2018 19:26:11 +0000 Subject: [PATCH 28/30] Adjusted package version and replaced helper function. --- package.json | 2 +- src/assets/ElmAsset.js | 27 ++------------------------- 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 49432f73ccf..b8438bb5bc6 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "codecov": "^3.0.0", "coffeescript": "^2.0.3", "cross-env": "^5.1.1", - "elm": "^0.19.0-bugfix2", + "elm": "^0.19.0", "eslint": "^4.13.0", "find-elm-dependencies": "^2.0.0", "glslify-bundle": "^5.0.0", diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index 11292ab58ef..de4528a21b6 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -1,7 +1,5 @@ -const path = require('path'); const process = require('process'); const Asset = require('../Asset'); -const fs = require('../utils/fs'); const localRequire = require('../utils/localRequire'); const {minify} = require('terser'); @@ -17,34 +15,13 @@ class ElmAsset extends Asset { 'find-elm-dependencies', this.name ); - const dependencies = await findAllDependencies(this.name); - const packageFile = await findPackageFile(path.dirname(this.name)); - if (packageFile) { - dependencies.push(packageFile); - } + await this.getConfig(['elm.json'], {load: false}); + const dependencies = await findAllDependencies(this.name); dependencies.forEach(dependency => { this.addDependency(dependency, {includedInParent: true}); }); - - // Recursively search for a package file - async function findPackageFile(baseDir) { - const parsedPath = path.parse(baseDir); - const elmPackagePath = path.join(parsedPath.dir, 'elm.json'); - - if (await fs.exists(elmPackagePath)) { - return elmPackagePath; - } - - // Stop if we've reached the file system root - if (parsedPath.root === parsedPath.dir) { - return undefined; - } - - // Continue searching - return await findPackageFile(path.dirname(baseDir)); - } } async parse() { From 71358f42cfe014a6f4750fbc2b479dc7281db3e4 Mon Sep 17 00:00:00 2001 From: Ben Hanna Date: Sun, 23 Sep 2018 13:09:56 +0000 Subject: [PATCH 29/30] Removed a redundant package. --- package.json | 1 - src/assets/ElmAsset.js | 11 +++-------- yarn.lock | 8 ++++---- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index b8438bb5bc6..f42e636fb55 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,6 @@ "cross-env": "^5.1.1", "elm": "^0.19.0", "eslint": "^4.13.0", - "find-elm-dependencies": "^2.0.0", "glslify-bundle": "^5.0.0", "glslify-deps": "^1.3.0", "graphql": "^0.11.7", diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index de4528a21b6..c7a8028a345 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -11,13 +11,8 @@ class ElmAsset extends Asset { } async collectDependencies() { - const {findAllDependencies} = await localRequire( - 'find-elm-dependencies', - this.name - ); - await this.getConfig(['elm.json'], {load: false}); - const dependencies = await findAllDependencies(this.name); + const dependencies = await this.elm.findAllDependencies(this.name); dependencies.forEach(dependency => { this.addDependency(dependency, {includedInParent: true}); @@ -25,7 +20,7 @@ class ElmAsset extends Asset { } async parse() { - const elm = await localRequire('node-elm-compiler', this.name); + this.elm = await localRequire('node-elm-compiler', this.name); const options = { cwd: process.cwd() @@ -39,7 +34,7 @@ class ElmAsset extends Asset { options.optimize = true; } - const compiled = await elm.compileToString(this.name, options); + const compiled = await this.elm.compileToString(this.name, options); this.contents = compiled.toString(); } diff --git a/yarn.lock b/yarn.lock index 15173e7f341..25756f936b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2702,9 +2702,9 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" -elm@^0.19.0-bugfix2: - version "0.19.0-bugfix2" - resolved "https://registry.yarnpkg.com/elm/-/elm-0.19.0-bugfix2.tgz#b2b7ad4dbeb89edf997759330b3694f419f9f1b3" +elm@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/elm/-/elm-0.19.0.tgz#c6ad86afea9e971424ebe75e36c9d03412a787fa" dependencies: binwrap "0.1.4" @@ -3091,7 +3091,7 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" -find-elm-dependencies@2.0.0, find-elm-dependencies@^2.0.0: +find-elm-dependencies@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/find-elm-dependencies/-/find-elm-dependencies-2.0.0.tgz#435aa05a6544a0ecf54c5d1ac85cc1ca1044e4e4" dependencies: From d856fd6af7e4cc762da0af29d689fd73cf08a399 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Sun, 23 Sep 2018 21:52:44 -0700 Subject: [PATCH 30/30] Auto install elm and create elm.json if needed --- src/assets/ElmAsset.js | 66 ++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/src/assets/ElmAsset.js b/src/assets/ElmAsset.js index c7a8028a345..6ee40f0ed56 100644 --- a/src/assets/ElmAsset.js +++ b/src/assets/ElmAsset.js @@ -1,7 +1,10 @@ const process = require('process'); const Asset = require('../Asset'); +const commandExists = require('command-exists'); const localRequire = require('../utils/localRequire'); const {minify} = require('terser'); +const path = require('path'); +const spawn = require('cross-spawn'); class ElmAsset extends Asset { constructor(name, options) { @@ -10,34 +13,65 @@ class ElmAsset extends Asset { this.hmrPageReload = true; } - async collectDependencies() { - await this.getConfig(['elm.json'], {load: false}); - const dependencies = await this.elm.findAllDependencies(this.name); + async parse() { + let options = { + cwd: path.dirname(this.name) + }; - dependencies.forEach(dependency => { - this.addDependency(dependency, {includedInParent: true}); - }); - } + // If elm is not installed globally, install it locally. + try { + await commandExists('elm'); + } catch (err) { + await localRequire('elm', this.name); + options.pathToElm = path.join( + path.dirname(require.resolve('elm')), + 'bin', + 'elm' + ); + } - async parse() { this.elm = await localRequire('node-elm-compiler', this.name); - const options = { - cwd: process.cwd() - }; + // Ensure that an elm.json file exists, and initialize one if not. + let elmConfig = await this.getConfig(['elm.json'], {load: false}); + if (!elmConfig) { + await this.createElmConfig(options); - if (process.env.NODE_ENV === 'test') { - options.cwd = this.options.rootDir; + // Ensure we are watching elm.json for changes + await this.getConfig(['elm.json'], {load: false}); } if (this.options.minify) { options.optimize = true; } - const compiled = await this.elm.compileToString(this.name, options); + let compiled = await this.elm.compileToString(this.name, options); this.contents = compiled.toString(); } + async collectDependencies() { + let dependencies = await this.elm.findAllDependencies(this.name); + for (let dependency of dependencies) { + this.addDependency(dependency, {includedInParent: true}); + } + } + + async createElmConfig(options) { + let cp = spawn(options.pathToElm || 'elm', ['init']); + cp.stdin.write('y\n'); + + return new Promise((resolve, reject) => { + cp.on('error', reject); + cp.on('close', function(code) { + if (code !== 0) { + return reject(new Error('elm init failed.')); + } + + return resolve(); + }); + }); + } + async generate() { let output = this.contents; @@ -53,7 +87,7 @@ class ElmAsset extends Asset { // Based on: // - http://elm-lang.org/0.19.0/optimize function pack(source) { - const options = { + let options = { compress: { keep_fargs: false, passes: 2, @@ -83,7 +117,7 @@ class ElmAsset extends Asset { rename: false }; - const result = minify(source, options); + let result = minify(source, options); if (result.error) { throw result.error;