Browse Source

chore(parcel): Get working with pipeline.

jackyalcine 11 months ago
parent
commit
c25e6186e1
Signed by: Jacky Alciné <yo@jacky.wtf> GPG Key ID: 36CD7728BDFD66FF

+ 6
- 0
.browserslistrc View File

@@ -0,0 +1,6 @@
1
+last 2 Chrome versions
2
+last 2 Firefox versions
3
+last 2 Safari versions
4
+last 2 Edge versions
5
+last 4 iOS versions
6
+last 2 ChromeAndroid versions

+ 1
- 0
.gitignore View File

@@ -23,3 +23,4 @@ tmp/docker/
23 23
 tmp/storage/.gitkeep
24 24
 .sobelow
25 25
 node_modules
26
+priv/static

+ 46
- 0
.postcssrc.js View File

@@ -0,0 +1,46 @@
1
+const ENV = process.env.ENV;
2
+const path = require('path');
3
+
4
+module.exports = {
5
+  parser: 'postcss-scss',
6
+  plugins: {
7
+    'postcss-reporter': {
8
+      clearMessages: false
9
+    },
10
+    'postcss-url': [
11
+      {
12
+        url: 'copy',
13
+        basePath: path.resolve('node_modules/typeface-source-sans-pro'),
14
+        assetsPath: "../fonts",
15
+        useHash: false
16
+      },
17
+    ],
18
+    autoprefixer: {},
19
+    pixrem: {},
20
+    'postcss-combine-duplicated-selectors': {},
21
+    'postcss-light-text': {},
22
+    'postcss-reporter': {},
23
+    'postcss-ordered-values': {},
24
+    'postcss-reduce-initial': {},
25
+    'postcss-strip-inline-comments': {},
26
+    'postcss-pxtorem': {},
27
+    cssnano: ENV === 'production' ? {
28
+      preset: [
29
+        'default',
30
+        {
31
+          calc: true,
32
+          colormin: true,
33
+          discardUnused: true,
34
+          normalizeUrl: true
35
+        }
36
+      ]
37
+    } : false,
38
+    'postcss-pxtorem': {
39
+      unitPrecision: 4,
40
+      propWhiteList: [],
41
+      replace: true,
42
+      selectorBlackList: [],
43
+      minPixelValue: 4
44
+    },
45
+  }
46
+};

+ 9
- 0
.sassrc.js View File

@@ -0,0 +1,9 @@
1
+const path = require('path')
2
+const CWD = process.cwd()
3
+
4
+module.exports = {
5
+  "includePaths": [
6
+    path.resolve(CWD, 'node_modules'),
7
+    path.resolve(CWD, 'web/static/css'),
8
+  ]
9
+}

.stylelintrc → .stylelintrc.json View File

@@ -1,4 +1,5 @@
1 1
 {
2
+  "extends": "stylelint-config-recommended-scss",
2 3
   "rules": {
3 4
     "block-no-empty": null,
4 5
     "color-no-invalid-hex": true,
@@ -14,6 +15,7 @@
14 15
       "except": ["first-nested"],
15 16
       "ignore": ["after-comment"]
16 17
     } ],
17
-    "unit-whitelist": ["em", "rem", "%", "s"]
18
+    "unit-whitelist": ["em", "rem", "%", "s"],
19
+    "indentation": 2
18 20
   }
19 21
 }

+ 2
- 3
config/dev.exs View File

@@ -7,7 +7,7 @@ config :koype, Koype.Web.Endpoint,
7 7
   debug_errors: true,
8 8
   code_reloader: true,
9 9
   check_origin: false,
10
-  watchers: [],
10
+  watchers: [sh: ["priv/watchers/npm-parcel"]],
11 11
   reloadable_compilers: [
12 12
     :gettext,
13 13
     :elixir
@@ -20,8 +20,7 @@ config :koype, Koype.Web.Endpoint,
20 20
       ~r{web/views/.*(ex)$},
21 21
       ~r{web/templates/.*(eex)$}
22 22
     ]
23
-  ],
24
-  watchers: [node: ["npm", "parcel:watch"]]
23
+  ]
25 24
 
26 25
 config :logger, level: :debug
27 26
 config :logger, :console, format: {PrettyPrintFormatter, :write}

+ 11
- 0
cssnano.config.js View File

@@ -0,0 +1,11 @@
1
+module.exports = {
2
+  preset: [
3
+    'default',
4
+    {
5
+      calc: false,
6
+      discardComments: {
7
+        removeAll: true
8
+      }
9
+    }
10
+  ]
11
+}

+ 4
- 4
docker/scripts/docker-build.sh View File

@@ -1,5 +1,8 @@
1 1
 #!/bin/sh
2 2
 
3
+echo " ---> [npm] Pulling dependencies..."
4
+npm install || exit 50
5
+
3 6
 echo " ---> [mix] Preparing..."
4 7
 mix local.hex --force || exit 10
5 8
 mix local.rebar --force || exit 10
@@ -14,7 +17,4 @@ mix deps.compile || exit 30
14 17
 echo " ---> [mix] Compiling application..."
15 18
 mix compile || exit 40
16 19
 
17
-echo " ---> [npm] Pulling dependencies..."
18
-npm install || exit 50
19
-
20
-echo " ---> [mix] Application built."
20
+echo " ---> [koype] Application built."

+ 2426
- 111
package-lock.json
File diff suppressed because it is too large
View File


+ 39
- 2
package.json View File

@@ -8,7 +8,8 @@
8 8
     "test": "test"
9 9
   },
10 10
   "scripts": {
11
-    "parcel:watch": "parcel watch web/static/js/koype.js web/static/css/koype.css --out-dir priv/static/ --cache-dir tmp/parcel --log-level 3"
11
+    "parcel:watch": "parcel watch web/static/koype.ts --out-dir priv/static --cache-dir tmp/parcel",
12
+    "parcel:build": "parcel build web/static/koype.ts web/static/koype.scss --out-dir priv/static --cache-dir tmp/parcel --log-level 4 --detailed-report"
12 13
   },
13 14
   "repository": {
14 15
     "type": "git",
@@ -17,10 +18,46 @@
17 18
   "author": "Jacky Alciné <yo@jacky.wtf> (https://jacky.wtf/)",
18 19
   "license": "AGPL-3.0-only",
19 20
   "dependencies": {
20
-    "parcel-bundler": "1.10.3"
21
+    "autoprefixer": "9.3.1",
22
+    "cssnano": "4.1.7",
23
+    "feather-icons": "4.9.0",
24
+    "leaflet": "1.3.4",
25
+    "parcel-bundler": "1.10.3",
26
+    "phoenix": "file:deps/phoenix",
27
+    "phoenix_html": "file:deps/phoenix_html",
28
+    "pixrem": "4.0.1",
29
+    "postcss-cachebuster": "0.1.5",
30
+    "postcss-combine-duplicated-selectors": "6.1.0",
31
+    "postcss-light-text": "0.0.1",
32
+    "postcss-load-config": "2.0.0",
33
+    "postcss-reporter": "6.0.0",
34
+    "postcss-scss": "2.0.0",
35
+    "postcss-strip-inline-comments": "0.1.5",
36
+    "pretty-checkbox": "3.0.3",
37
+    "qrcode-generator": "1.4.1",
38
+    "sweet-alert": "^2.0.5",
39
+    "tachyons": "4.10.0",
40
+    "tachyons-sass": "4.9.5",
41
+    "typeface-source-code-pro": "0.0.54",
42
+    "typeface-source-sans-pro": "0.0.54",
43
+    "typeface-source-serif-pro": "0.0.54",
44
+    "webfontloader": "^1.6.28"
21 45
   },
22 46
   "engines": {
23 47
     "node": "8.14.0",
24 48
     "npm": "6.4.0"
49
+  },
50
+  "devDependencies": {
51
+    "parcel-plugin-bundle-visualiser": "1.2.0",
52
+    "postcss-hash": "^1.0.2",
53
+    "postcss-import": "12.0.1",
54
+    "postcss-plugin": "^1.0.0",
55
+    "postcss-pxtorem": "^4.0.1",
56
+    "postcss-url": "^8.0.0",
57
+    "sass": "1.15.1",
58
+    "stylelint": "9.9.0",
59
+    "stylelint-config-recommended-scss": "3.2.0",
60
+    "stylelint-scss": "3.4.0",
61
+    "typescript": "^3.2.1"
25 62
   }
26 63
 }

+ 3
- 0
priv/watchers/npm-parcel View File

@@ -0,0 +1,3 @@
1
+#!/bin/env sh
2
+
3
+npm run parcel:watch

+ 9
- 1
web/endpoint.ex View File

@@ -4,12 +4,20 @@ defmodule Koype.Web.Endpoint do
4 4
 
5 5
   socket("/socket", Koype.Web.UserSocket)
6 6
 
7
+  plug(
8
+    Plug.Static,
9
+    at: "/assets",
10
+    from: :koype,
11
+    gzip: :true,
12
+    only_matching: ~w(koype source)
13
+  )
14
+
7 15
   plug(
8 16
     Plug.Static,
9 17
     at: "/",
10 18
     from: :koype,
11 19
     gzip: true,
12
-    only: ~w(css fonts images js favicon.ico robots.txt)
20
+    only: ~w(assets images favicon.ico robots.txt)
13 21
   )
14 22
 
15 23
   if code_reloading? do

+ 0
- 57
web/static/css/koype.css View File

@@ -1,57 +0,0 @@
1
-@import url("https://rsms.me/inter/inter-ui.css");
2
-
3
-html.wf-cantarell-n4-active h1,
4
-html.wf-cantarell-n4-active h2,
5
-html.wf-cantarell-n4-active h3,
6
-html.wf-cantarell-n4-active h4,
7
-html.wf-cantarell-n4-active h5,
8
-html.wf-cantarell-n4-active h6,
9
-html.wf-cantarell-n4-active .serif {
10
-  font-family: Cantarell, Times, serif;
11
-}
12
-
13
-html.wf-interui-n4-active input,
14
-html.wf-interui-n4-active button,
15
-html.wf-interui-n4-active form,
16
-html.wf-interui-n4-active p,
17
-html.wf-interui-n4-active blockquote,
18
-html.wf-interui-n4-active article,
19
-html.wf-interui-n4-active aside,
20
-html.wf-interui-n4-active main,
21
-html.wf-interui-n4-active footer,
22
-html.wf-interui-n4-active header,
23
-html.wf-interui-n4-active .sans-serif {
24
-  font-family: "Inter UI", sans-serif;
25
-}
26
-
27
-html.wf-hack-n4-active pre,
28
-html.wf-hack-n4-active code,
29
-html.wf-hack-n4-active kbd,
30
-html.wf-hack-n4-active .code {
31
-  font-family: "Hack", monospace;
32
-}
33
-
34
-.e-content p {
35
-  margin: 0rem auto;
36
-  text-align: justify;
37
-  text-align-last: left;
38
-}
39
-
40
-.e-content p:first-child {
41
-  font-size: 120%;
42
-}
43
-
44
-.e-content p:first-child::first-line {
45
-  font-size: 140%;
46
-}
47
-
48
-.e-content pre {
49
-  background-color: black;
50
-  color: green;
51
-  padding: 1.5rem 0rem;
52
-  line-height: 1;
53
-}
54
-
55
-i[data-feather] {
56
-  display: inline-block;
57
-}

+ 0
- 56
web/static/js/koype.js View File

@@ -1,56 +0,0 @@
1
-"use strict";
2
-
3
-(function() {
4
-  function buildHiddenInput(name, value) {
5
-    var input = document.createElement("input");
6
-    input.type = "hidden";
7
-    input.name = name;
8
-    input.value = value;
9
-    return input;
10
-  }
11
-
12
-  function handleLinkClick(link) {
13
-    var message = link.getAttribute("data-confirm");
14
-    if (message && !window.confirm(message)) {
15
-      return;
16
-    }
17
-
18
-    var to = link.getAttribute("data-to"),
19
-      method = buildHiddenInput("_method", link.getAttribute("data-method")),
20
-      csrf = buildHiddenInput("_csrf_token", link.getAttribute("data-csrf")),
21
-      form = document.createElement("form");
22
-
23
-    form.method = "post";
24
-    form.action = to;
25
-    form.style.display = "hidden";
26
-
27
-    form.appendChild(csrf);
28
-    form.appendChild(method);
29
-    document.body.appendChild(form);
30
-    form.submit();
31
-  }
32
-
33
-  window.addEventListener("click", function(e) {
34
-    if (e.target && e.target.getAttribute("data-method")) {
35
-      handleLinkClick(e.target);
36
-    }
37
-  }, false);
38
-
39
-  window.addEventListener('load', function() {
40
-    WebFont.load({
41
-      google: {
42
-        families: ['Cantarell']
43
-      },
44
-      custom: {
45
-        families: ['Hack', 'Inter UI']
46
-      },
47
-      active: function() {
48
-        sessionStorage.fonts = true;
49
-      }
50
-    });
51
-
52
-    feather.replace();
53
-
54
-    fitterHappierText(document.querySelectorAll('[data-fitter]'));
55
-  });
56
-})();

+ 0
- 1431
web/static/js/phoenix.js
File diff suppressed because it is too large
View File


+ 48
- 0
web/static/koype.scss View File

@@ -0,0 +1,48 @@
1
+@import "tachyons-custom/src/tachyons.css";
2
+@import "typeface-source-sans-pro/index.css";
3
+@import "typeface-source-serif-pro/index.css";
4
+@import "typeface-source-code-pro/index.css";
5
+
6
+.e-content {
7
+  p {
8
+    margin: 0rem auto;
9
+    text-align: justify;
10
+    text-align-last: left;
11
+
12
+    &:first-child {
13
+      font-size: 120%;
14
+    }
15
+
16
+    &:first-child::first-line {
17
+      font-size: 140%;
18
+    }
19
+  }
20
+
21
+  pre {
22
+    background-color: black;
23
+    color: green;
24
+    padding: 1.5rem 0rem;
25
+    line-height: 1;
26
+  }
27
+}
28
+
29
+html.wf-active {
30
+  h1, h2, h3, h4, h5, h6, p
31
+  blockquote, .sans-serif {
32
+    font-family: "Source Sans Pro", sans-serif;
33
+  }
34
+
35
+  input, button, form,
36
+  article, aside,
37
+  main, footer, header,
38
+  .serif {
39
+    font-family: "Source Serif Pro", serif;
40
+  }
41
+
42
+  pre, code, kbd,
43
+  .mono {
44
+    font-family: "Source Mono Pro", monospace;
45
+  }
46
+}
47
+
48
+@import "leaflet/dist/leaflet.css";

+ 59
- 0
web/static/koype.ts View File

@@ -0,0 +1,59 @@
1
+import WebFont from 'webfontloader';
2
+import feather from 'feather-icons';
3
+import swal from 'sweet-alert';
4
+
5
+import 'phoenix_html';
6
+import { Socket } from 'phoenix';
7
+
8
+function buildHiddenInput(name, value) {
9
+  var input = document.createElement("input");
10
+  input.type = "hidden";
11
+  input.name = name;
12
+  input.value = value;
13
+  return input;
14
+}
15
+
16
+function handleLinkClick(link) {
17
+  var message = link.getAttribute("data-confirm");
18
+
19
+  // TODO: Replace this with sweet-alert.
20
+  if (message && !window.confirm(message)) {
21
+    return;
22
+  }
23
+
24
+  var to = link.getAttribute("data-to"),
25
+    method = buildHiddenInput("_method", link.getAttribute("data-method")),
26
+    csrf = buildHiddenInput("_csrf_token", link.getAttribute("data-csrf")),
27
+    form = document.createElement("form");
28
+
29
+  form.method = "post";
30
+  form.action = to;
31
+  form.style.display = "hidden";
32
+
33
+  form.appendChild(csrf);
34
+  form.appendChild(method);
35
+  document.body.appendChild(form);
36
+  form.submit();
37
+}
38
+
39
+window.addEventListener("click", function(e) {
40
+  if (e.target) {
41
+    const elem: Element = e.target;
42
+    if (elem.getAttribute("data-method")) {
43
+      handleLinkClick(elem);
44
+    }
45
+  }
46
+}, false);
47
+
48
+window.addEventListener('load', function() {
49
+  feather.replace();
50
+
51
+  WebFont.load({
52
+    custom: {
53
+      families: ['Source+Sans+Pro', 'Source Serif Pro', 'Source Code Pro']
54
+    },
55
+    active: function() {
56
+      sessionStorage.fonts = true;
57
+    }
58
+  });
59
+});

+ 1
- 1
web/templates/entry/_feedback.html.eex View File

@@ -1,4 +1,4 @@
1
-<div class="db bg-near-black mt4-s ma3-l self-start order-1 w-100 w-auto-ns self-stretch items-center">
1
+<div class="db bg-near-black mt4-s ma3-l self-start order-1 w-100 w-auto-ns self-stretch items-center sans-serif">
2 2
   <ul class="flex flex-column w-100 h-100 justify-center w-auto-l ba b--near-black relative-l left-1-l bottom-1-l self-end-l self-center ma0 pa3 f6 gray list lh-copy bg-dark-gray moon-gray">
3 3
     <li class="lh-copy">
4 4
       <a href="#mentions-reposts" class="link color-inherit dim">

+ 1
- 1
web/templates/entry/_sparkline.html.eex View File

@@ -1,4 +1,4 @@
1
-<div class="db bg-near-black mt3 mt0-m ma3-l self-start w-100 w-auto-ns order-2 order-3-l self-stretch items-center">
1
+<div class="db bg-near-black mt3 mt0-m ma3-l self-start w-100 w-auto-ns order-2 order-3-l self-stretch items-center sans-serif">
2 2
   <ul class="flex flex-column w-100 h-100 justify-center w-auto-l relative-l left--1-l top--1-l self-end-l self-center ma0 pa3 f6 gray list lh-copy bg-lightest-blue near-black ba b--mid-gray">
3 3
     <li class="lh-copy">
4 4
     <%= if !is_nil(@entry[:published]) do %>

+ 2
- 20
web/templates/layout/app.html.eex View File

@@ -4,10 +4,6 @@
4 4
     <meta charset="utf-8">
5 5
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 6
     <base href="<%= Koype.host %>" target="_self">
7
-    <link rel="preconnect" href="https://fonts.google.com" crossorigin>
8
-    <link rel="preconnect" href="https://unpkg.com" crossorigin>
9
-    <link rel="preconnect" href="https://jsdelivr.net" crossorigin>
10
-    <link rel="preconnect" href="https://ajax.googleapis.com" crossorigin>
11 7
 
12 8
     <!-- Metadata -->
13 9
     <%= for name <- Koype.Web.tags(:meta) ++ @view_module.tags(:meta, @view_template, assigns) do %>
@@ -24,14 +20,7 @@
24 20
     <link rel="icon" type="image/x-icon" href="<%= static_path(@conn, "/images/favicon.png") %>" />
25 21
 
26 22
     <!-- Styling -->
27
-    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>" />
28
-    <link rel="stylesheet" href="//unpkg.com/tachyons@4.10.0/css/tachyons.min.css" />
29
-    <link rel="stylesheet" src="//unpkg.com/gradients" />
30
-    <link rel="stylesheet" href="//unpkg.com/leaflet@1.3.4/dist/leaflet.css"
31
-      integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
32
-      crossorigin=""/>
33
-    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/pretty-checkbox@3.0/dist/pretty-checkbox.min.css" />
34
-    <link rel='stylesheet' href='//cdn.jsdelivr.net/npm/hack-font@3.3.0/build/web/hack.css'>
23
+    <link rel="stylesheet" href="<%= static_path(@conn, "/assets/koype.css") %>" />
35 24
   </head>
36 25
   <body class="w-100 min-h-100 min-vh-100 flex flex-column near-black bg-near-white sans-serif">
37 26
     <%= render Koype.Web.PageView, "_header.html", assigns %>
@@ -41,13 +30,6 @@
41 30
     </main>
42 31
     <%= render Koype.Web.PageView, "_now-sparkline.html", assigns %>
43 32
     <%= render Koype.Web.PageView, "_footer.html", assigns %>
44
-    <script async defer src="//unpkg.com/feather-icons"></script>
45
-    <script async defer src="//unpkg.com/qrcode-generator"></script>
46
-    <script async defer src="//unpkg.com/fitter-happier-text@0.0.7/dist/fitter-happier-text.js"></script>
47
-    <script src="//unpkg.com/leaflet@1.3.4/dist/leaflet.js"
48
-      integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA=="
49
-      crossorigin=""></script>
50
-    <script async defer src="//ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
51
-    <script async defer src="<%= static_path(@conn, "/js/app.js") %>"></script>
33
+    <script async defer src="<%= static_path(@conn, "/assets/koype.js") %>"></script>
52 34
   </body>
53 35
 </html>

+ 1
- 1
web/templates/page/_footer.html.eex View File

@@ -1,4 +1,4 @@
1
-<footer role="main" class="w-100 pa2 bg-navy bg-navy-gradient lightest-blue cb cf order-4 items-center">
1
+<footer role="main" class="w-100 pa2 bg-navy bg-navy-gradient lightest-blue cb cf order-4 items-center sans-serif">
2 2
   <div class="mw8 flex flex-column flex-row-l justify-around center">
3 3
     <%= if Koype.Profile.complete? do %>
4 4
       <div class="h-card pa2 items-center flex flex-column flex-row-l flex-auto flex-grow items-start">

+ 1
- 1
web/templates/page/_header.html.eex View File

@@ -1,7 +1,7 @@
1 1
 <header role="main" class="w-100 order-1 items-center">
2 2
   <div class="flex flex-column flex-row-l justify-between items-center pa2 center mw7 w-100">
3 3
     <a class="pa1 mv2 w-100 w-auto-l grow dim link gray tc" href="<%= page_path(@conn, :index) %>">
4
-      <span class="serif fw1 f4 f3-l tracked-tight v-mid">
4
+      <span class="sans-serif fw1 f4 f3-l tracked-tight v-mid">
5 5
         <%= Koype.Profile.displayed_name %>
6 6
       </span>
7 7
     </a>

+ 1
- 2
web/templates/page/_now-sparkline.html.eex View File

@@ -1,3 +1,2 @@
1
-<aside role="main" class="w-100 pa2 bg-blue lightest-yellow cb cf order-3 items-center">
2
-
1
+<aside role="main" class="w-100 ph2 bg-blue lightest-yellow cb cf order-3 items-center">
3 2
 </aside>

Loading…
Cancel
Save