@nzz/q-cli 1.5.4 → 1.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/.vscode/settings.json +5 -0
  2. package/README.md +16 -1
  3. package/bin/commands/bootstrap.js +6 -0
  4. package/dev-server/routes/rendering-info.js +0 -1
  5. package/dev-server/routes/tool-default.js +0 -2
  6. package/package.json +1 -1
  7. package/skeletons/custom-code-skeleton/.nvmrc +1 -1
  8. package/skeletons/custom-code-skeleton/.vscode/settings.json +5 -0
  9. package/skeletons/custom-code-skeleton/package-lock.json +5335 -627
  10. package/skeletons/custom-code-skeleton/package.json +10 -7
  11. package/skeletons/custom-code-skeleton/rollup.config.js +63 -17
  12. package/skeletons/custom-code-skeleton/src/App.scss +3 -0
  13. package/skeletons/custom-code-skeleton/src/App.svelte +1 -7
  14. package/skeletons/custom-code-skeleton/src/main-prod.js +1 -0
  15. package/skeletons/custom-code-skeleton/src/main.js +1 -0
  16. package/skeletons/custom-code-skeleton/src/main.scss +1 -0
  17. package/skeletons/server-skeleton/auth/routes.js +0 -9
  18. package/skeletons/server-skeleton/index.js +1 -3
  19. package/skeletons/tool-skeleton/.nvmrc +1 -1
  20. package/skeletons/tool-skeleton/.travis.yml +26 -0
  21. package/skeletons/tool-skeleton/.vscode/settings.json +5 -0
  22. package/skeletons/tool-skeleton/Dockerfile +1 -1
  23. package/skeletons/tool-skeleton/LICENSE +20 -0
  24. package/skeletons/tool-skeleton/README.md +1 -1
  25. package/skeletons/tool-skeleton/index.js +1 -6
  26. package/skeletons/tool-skeleton/package-lock.json +8540 -2741
  27. package/skeletons/tool-skeleton/package.json +24 -12
  28. package/skeletons/tool-skeleton/rollup.config.js +75 -0
  29. package/skeletons/tool-skeleton/routes/fixtures/data.js +1 -3
  30. package/skeletons/tool-skeleton/routes/rendering-info/web.js +43 -20
  31. package/skeletons/tool-skeleton/routes/routes.js +1 -1
  32. package/skeletons/tool-skeleton/routes/script.js +4 -5
  33. package/skeletons/tool-skeleton/routes/stylesheet.js +4 -5
  34. package/skeletons/tool-skeleton/sass.config.js +66 -0
  35. package/skeletons/tool-skeleton/scripts_src/default.js +3 -0
  36. package/skeletons/tool-skeleton/styles_src/_variables.scss +1 -0
  37. package/skeletons/tool-skeleton/styles_src/main.scss +2 -0
  38. package/skeletons/tool-skeleton/test/e2e-tests.js +4 -6
  39. package/skeletons/tool-skeleton/views/dynamic/YourTool.scss +5 -0
  40. package/skeletons/tool-skeleton/views/dynamic/YourTool.svelte +19 -0
  41. package/skeletons/tool-skeleton/views/static/App.scss +5 -0
  42. package/skeletons/tool-skeleton/views/static/App.svelte +21 -0
  43. package/skeletons/tool-skeleton/views/static/components/Footer.svelte +31 -0
  44. package/skeletons/tool-skeleton/views/static/components/Header.svelte +7 -0
  45. package/skeletons/tool-skeleton/styles_src/default.scss +0 -4
  46. package/skeletons/tool-skeleton/tasks/build.js +0 -98
@@ -4,7 +4,10 @@
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "build": "rm -rf styles && mkdir styles && node tasks/build.js",
7
+ "build": "rollup -c",
8
+ "autobuild": "rollup -c -w",
9
+ "dev": "run-p autobuild start",
10
+ "start": "nodemon index.js",
8
11
  "test": "lab -a @hapi/code -c -P tests --verbose --leaks"
9
12
  },
10
13
  "author": "",
@@ -14,20 +17,29 @@
14
17
  "url": "https://github.com/github/tool-skeleton.git"
15
18
  },
16
19
  "dependencies": {
17
- "@hapi/boom": "^9.1.1",
18
- "@hapi/hapi": "^20.1.3",
19
- "@hapi/inert": "^6.0.3",
20
- "ajv": "^6.12.6",
21
- "joi": "^17.4.0"
20
+ "@hapi/boom": "^9.1.4",
21
+ "@hapi/hapi": "^20.2.0",
22
+ "@hapi/inert": "^6.0.4",
23
+ "ajv": "^8.6.3",
24
+ "joi": "^17.4.2",
25
+ "svelte": "^3.44.2"
22
26
  },
23
27
  "devDependencies": {
24
28
  "@hapi/code": "^8.0.3",
25
- "@hapi/lab": "^22.0.5",
26
- "autoprefixer": "^10.2.5",
27
- "cssnano": "^4.1.11",
29
+ "@hapi/lab": "^24.3.2",
30
+ "@rollup/plugin-commonjs": "^21.0.0",
31
+ "@rollup/plugin-node-resolve": "^13.0.5",
32
+ "autoprefixer": "^10.4.0",
33
+ "cssnano": "^5.0.10",
28
34
  "glob": "^7.1.7",
29
- "postcss": "^8.3.0",
30
- "postcss-import": "^14.0.2",
31
- "sass": "^1.34.0"
35
+ "nodemon": "^2.0.13",
36
+ "npm-run-all": "^4.1.5",
37
+ "postcss": "^8.3.11",
38
+ "rollup": "^2.60.0",
39
+ "rollup-plugin-livereload": "^2.0.5",
40
+ "rollup-plugin-scss": "^3.0.0",
41
+ "rollup-plugin-svelte": "^7.1.0",
42
+ "rollup-plugin-terser": "^7.0.2",
43
+ "sass": "^1.43.4"
32
44
  }
33
45
  }
@@ -0,0 +1,75 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import * as crypto from "crypto";
4
+ import nodeResolve from "@rollup/plugin-node-resolve";
5
+ import commonjs from "@rollup/plugin-commonjs";
6
+ import svelte from "rollup-plugin-svelte";
7
+ import { terser } from "rollup-plugin-terser";
8
+ import livereload from "rollup-plugin-livereload";
9
+ import scss from "rollup-plugin-scss";
10
+ const sassConfig = require("./sass.config");
11
+
12
+ const production = !process.env.ROLLUP_WATCH;
13
+ const scriptsDir = path.join(__dirname, "/scripts_src/");
14
+ const filename = "default";
15
+ const scriptDirDefaultFileName = path.join(scriptsDir, `/${filename}.js`);
16
+
17
+ function writeHashmap(hashmapPath, file, fileext) {
18
+ const hash = crypto.createHash("md5");
19
+ hash.update(file.content, { encoding: "utf8" });
20
+ file.hash = hash.digest("hex");
21
+
22
+ const hashMap = {};
23
+ hashMap[file.name] = `${file.name}.${file.hash.substring(0, 8)}.${fileext}`;
24
+ fs.writeFileSync(hashmapPath, JSON.stringify(hashMap));
25
+ }
26
+
27
+ function generateHashmap() {
28
+ return {
29
+ name: "generateHashmap",
30
+ async generateBundle(outputOptions, bundle, isWrite) {
31
+ const scriptsDir = "scripts";
32
+ // Create directory if not yet exist or recreate directory if it already exists
33
+ if (!fs.existsSync(scriptsDir)) {
34
+ fs.mkdirSync(scriptsDir);
35
+ } else {
36
+ fs.rmdirSync(scriptsDir, { recursive: true });
37
+ fs.mkdirSync(scriptsDir);
38
+ }
39
+ writeHashmap(
40
+ "scripts/hashMap.json",
41
+ {
42
+ name: filename,
43
+ content: bundle[`${filename}.js`].code,
44
+ },
45
+ "js"
46
+ );
47
+ },
48
+ };
49
+ }
50
+
51
+ export default {
52
+ input: scriptDirDefaultFileName,
53
+ output: {
54
+ format: "iife",
55
+ // TODO: Rename 'window._q_your_tool.YourTool' to 'window._q_<tool-name>.<ToolName>'
56
+ name: "window._q_your_tool.YourTool",
57
+ file: `scripts/${filename}.js`,
58
+ },
59
+ plugins: [
60
+ svelte(),
61
+ scss({ ...sassConfig.get(production, writeHashmap) }),
62
+ nodeResolve({ browser: true }),
63
+ commonjs(),
64
+ !production && livereload({ watch: ["scripts"], delay: 800 }),
65
+ production && terser(),
66
+ generateHashmap(),
67
+ ],
68
+ watch: {
69
+ clearScreen: false,
70
+ },
71
+ onwarn: function (warning, warn) {
72
+ if (warning.code === "CIRCULAR_DEPENDENCY") return;
73
+ warn(warning);
74
+ },
75
+ };
@@ -1,7 +1,6 @@
1
1
  const fixtureDataDirectory = "../../resources/fixtures/data";
2
2
 
3
3
  // provide every fixture data file present in ../../resources/fixtures/data
4
- // has to be in sync with files created in build task - see ../../tasks/build.js
5
4
  const fixtureData = [require(`${fixtureDataDirectory}/basic.json`)];
6
5
 
7
6
  module.exports = {
@@ -9,9 +8,8 @@ module.exports = {
9
8
  method: "GET",
10
9
  options: {
11
10
  tags: ["api"],
12
- cors: true
13
11
  },
14
12
  handler: (request, h) => {
15
13
  return fixtureData;
16
- }
14
+ },
17
15
  };
@@ -1,21 +1,32 @@
1
1
  const Boom = require("@hapi/boom");
2
2
  const fs = require("fs");
3
3
  const path = require("path");
4
+ const Ajv = require("ajv");
4
5
 
6
+ const staticViewsDir = path.join(__dirname, "/../../views/static/");
5
7
  const stylesDir = path.join(__dirname, "/../../styles/");
8
+ const scriptsDir = path.join(__dirname, "../../scripts/");
9
+
10
+ require("svelte/register");
11
+ const staticTemplate = require(path.join(
12
+ staticViewsDir,
13
+ "/App.svelte"
14
+ )).default;
15
+ const styles = fs.readFileSync(path.join(stylesDir, "/default.css")).toString();
6
16
  const styleHashMap = require(path.join(stylesDir, "hashMap.json"));
17
+ const scriptHashMap = require(path.join(scriptsDir, "hashMap.json"));
7
18
 
8
19
  // POSTed item will be validated against given schema
9
20
  // hence we fetch the JSON schema...
10
21
  const schemaString = JSON.parse(
11
22
  fs.readFileSync(path.join(__dirname, "../../resources/", "schema.json"), {
12
- encoding: "utf-8"
23
+ encoding: "utf-8",
13
24
  })
14
25
  );
15
- const Ajv = require("ajv");
16
- const ajv = new Ajv();
17
26
 
27
+ const ajv = new Ajv({ strict: false });
18
28
  const validate = ajv.compile(schemaString);
29
+
19
30
  function validateAgainstSchema(item, options) {
20
31
  if (validate(item)) {
21
32
  return item;
@@ -43,32 +54,44 @@ module.exports = {
43
54
  options: {
44
55
  validate: {
45
56
  options: {
46
- allowUnknown: true
57
+ allowUnknown: true,
47
58
  },
48
- payload: validatePayload
49
- }
59
+ payload: validatePayload,
60
+ },
50
61
  },
51
- handler: async function(request, h) {
52
- const item = request.payload.item;
62
+ handler: async function (request, h) {
63
+ const toolRuntimeConfig = request.payload.toolRuntimeConfig;
64
+ const context = {
65
+ // TODO: Rename 'q_your_tool_' to 'q_<tool_name>_'
66
+ id: `q_your_tool_${toolRuntimeConfig.requestId}`,
67
+ displayOptions: toolRuntimeConfig.displayOptions || {},
68
+ item: request.payload.item,
69
+ };
70
+
71
+ const staticTemplateRender = staticTemplate.render(context);
53
72
 
54
73
  const renderingInfo = {
55
74
  polyfills: ["Promise"],
56
- stylesheets: [
57
- {
58
- name: styleHashMap["default"]
59
- }
60
- ],
75
+ stylesheets: [{ content: styles }, { name: styleHashMap["default"] }],
61
76
  scripts: [
77
+ { name: scriptHashMap["default"] },
78
+ // TODO: Rename 'new window._q_your_tool.YourTool' to 'new window._q_<tool-name>.<ToolName>'
62
79
  {
63
- content:
64
- 'var p = new Promise(function(resolve) { resolve(); }) p.then(function() { console.log ("tool-skeleton script executed")});'
65
- }
80
+ content: `
81
+ (function () {
82
+ var target = document.querySelector('#${context.id}_container');
83
+ target.innerHTML = "";
84
+ var props = ${JSON.stringify(context)};
85
+ new window._q_your_tool.YourTool({
86
+ "target": target,
87
+ "props": props
88
+ })
89
+ })();`,
90
+ },
66
91
  ],
67
- markup: `<h1>${item.title}</h1><h2>${
68
- item.subtitle
69
- }</h2><p>rendered by tool-skeleton`
92
+ markup: staticTemplateRender.html,
70
93
  };
71
94
 
72
95
  return renderingInfo;
73
- }
96
+ },
74
97
  };
@@ -4,5 +4,5 @@ module.exports = [
4
4
  require("./script.js"),
5
5
  require("./health.js"),
6
6
  require("./fixtures/data.js"),
7
- require("./locales.js")
7
+ require("./locales.js"),
8
8
  ].concat(require("./schema.js"));
@@ -4,15 +4,14 @@ module.exports = {
4
4
  method: "GET",
5
5
  path: "/script/{filename}.{hash}.{extension}",
6
6
  options: {
7
- cors: true,
8
7
  files: {
9
- relativeTo: path.join(__dirname, "/../scripts/")
10
- }
8
+ relativeTo: path.join(__dirname, "/../scripts/"),
9
+ },
11
10
  },
12
- handler: function(request, h) {
11
+ handler: function (request, h) {
13
12
  return h
14
13
  .file(`${request.params.filename}.${request.params.extension}`)
15
14
  .type("text/javascript")
16
15
  .header("cache-control", `max-age=${60 * 60 * 24 * 365}, immutable`); // 1 year
17
- }
16
+ },
18
17
  };
@@ -4,15 +4,14 @@ module.exports = {
4
4
  method: "GET",
5
5
  path: "/stylesheet/{filename}.{hash}.{extension}",
6
6
  options: {
7
- cors: true,
8
7
  files: {
9
- relativeTo: path.join(__dirname, "/../styles/")
10
- }
8
+ relativeTo: path.join(__dirname, "/../styles/"),
9
+ },
11
10
  },
12
- handler: function(request, h) {
11
+ handler: function (request, h) {
13
12
  return h
14
13
  .file(`${request.params.filename}.${request.params.extension}`)
15
14
  .type("text/css")
16
15
  .header("cache-control", `max-age=${60 * 60 * 24 * 365}, immutable`); // 1 year
17
- }
16
+ },
18
17
  };
@@ -0,0 +1,66 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const postcss = require("postcss");
4
+ const autoprefixer = require("autoprefixer");
5
+ const cssnano = require("cssnano");
6
+
7
+ function createOutputCssFunction(writeHashmapFunction) {
8
+ const outputCssFunction = (styles, styleNodes) => {
9
+ const stylesDir = "styles";
10
+
11
+ if (!fs.existsSync(stylesDir)) {
12
+ fs.mkdirSync(stylesDir);
13
+ }
14
+
15
+ fs.writeFileSync(`styles/default.css`, styles);
16
+ writeHashmapFunction(
17
+ "styles/hashMap.json",
18
+ {
19
+ name: "default",
20
+ content: styles,
21
+ },
22
+ "css"
23
+ );
24
+ };
25
+
26
+ return outputCssFunction;
27
+ }
28
+
29
+ function getPostcssPlugins(isProduction) {
30
+ const postcssPlugins = [autoprefixer];
31
+
32
+ if (isProduction) {
33
+ postcssPlugins.push(cssnano);
34
+ }
35
+
36
+ return postcssPlugins;
37
+ }
38
+
39
+ function get(isProduction, writeHashmapFunction) {
40
+ const config = {
41
+ outputStyle: isProduction ? "compressed" : "expanded",
42
+ // Sourcemap generation (specifically writing the file to system) is currently not supported by rollup-plugin-sass (but soon!)
43
+ // See: https://github.com/thgh/rollup-plugin-scss/issues/7
44
+ // outFile: path.join(__dirname, "/styles/default.css"), // <- Uncomment after: https://github.com/thgh/rollup-plugin-scss/issues/7
45
+ sourceMap: !isProduction,
46
+ sourceMapEmbed: !isProduction, // Remove after: https://github.com/thgh/rollup-plugin-scss/issues/7
47
+ failOnError: !isProduction,
48
+ watch: [
49
+ path.join(__dirname, "/styles_src"),
50
+ path.join(__dirname, "/views"),
51
+ ],
52
+ processor: (css) =>
53
+ postcss(getPostcssPlugins(isProduction))
54
+ .process(css, {
55
+ from: path.join(__dirname, "/styles/default.css"),
56
+ to: path.join(__dirname, "/styles/default.css"),
57
+ map: isProduction ? false : { inline: true }, // Set to false after: https://github.com/thgh/rollup-plugin-scss/issues/7
58
+ })
59
+ .then((result) => result.css),
60
+ output: createOutputCssFunction(writeHashmapFunction),
61
+ };
62
+
63
+ return config;
64
+ }
65
+
66
+ module.exports = { get };
@@ -0,0 +1,3 @@
1
+ import YourTool from "./../views/dynamic/YourTool.svelte";
2
+ import "./../styles_src/main.scss";
3
+ export default YourTool;
@@ -0,0 +1 @@
1
+ $color: salmon;
@@ -0,0 +1,2 @@
1
+ @use "../views/static/App.scss";
2
+ @use "../views/dynamic/YourTool.scss";
@@ -20,9 +20,7 @@ before(async () => {
20
20
  try {
21
21
  server = Hapi.server({
22
22
  port: process.env.PORT || 3000,
23
- routes: {
24
- cors: true,
25
- },
23
+ routes: {},
26
24
  });
27
25
  server.validator(Joi);
28
26
  await server.register(require("@hapi/inert"));
@@ -103,7 +101,7 @@ lab.experiment("stylesheets endpoint", () => {
103
101
  });
104
102
 
105
103
  // all the fixtures render
106
- lab.experiment("all fixtures render", async () => {
104
+ lab.experiment("all fixtures render", () => {
107
105
  const fixtureFiles = glob.sync(
108
106
  `${__dirname}/../resources/fixtures/data/*.json`
109
107
  );
@@ -143,7 +141,7 @@ lab.experiment("rendering-info", () => {
143
141
  });
144
142
 
145
143
  lab.experiment("assets", () => {
146
- it("returnes stylesheet", async () => {
144
+ it("returns stylesheet", async () => {
147
145
  const fixture = fs.readFileSync(
148
146
  `${__dirname}/../resources/fixtures/data/basic.json`,
149
147
  { encoding: "utf-8" }
@@ -157,7 +155,7 @@ lab.experiment("assets", () => {
157
155
  },
158
156
  });
159
157
  const stylesheetRes = await server.inject(
160
- `/stylesheet/${res.result.stylesheets[0].name}`
158
+ `/stylesheet/${res.result.stylesheets[1].name}`
161
159
  );
162
160
  expect(stylesheetRes.statusCode).to.be.equal(200);
163
161
  });
@@ -0,0 +1,5 @@
1
+ @use "variables";
2
+
3
+ .your-tool__is-working-label {
4
+ color: variables.$color !important; // Please refrain from using '!important' :)
5
+ }
@@ -0,0 +1,19 @@
1
+ <script>
2
+ // TODO: Rename 'YourTool.svelte' to '<Tool-Name>.svelte' & change all references
3
+ let isWorkingLabel = "";
4
+ let i = 0;
5
+
6
+ function worksOnClick() {
7
+ i++;
8
+ isWorkingLabel = i < 5 ? "is working!" : "is still working!";
9
+ }
10
+ </script>
11
+
12
+ <!-- Client side code is written/imported inside this component (e.g. Client interaction components) -->
13
+ <div class="s-font-title">
14
+ Client-Side code
15
+ <span class="your-tool__is-working-label">{isWorkingLabel}</span>
16
+ </div>
17
+ <button class="s-button s-button--small" on:click={worksOnClick}>
18
+ Click me!
19
+ </button>
@@ -0,0 +1,5 @@
1
+ @use "variables";
2
+
3
+ h3 {
4
+ color: variables.$color !important; // Please refrain from using '!important' :)
5
+ }
@@ -0,0 +1,21 @@
1
+ <script>
2
+ import Header from "./components/Header.svelte";
3
+ import Footer from "./components/Footer.svelte";
4
+
5
+ export let item;
6
+ export let id;
7
+ export let displayOptions;
8
+ </script>
9
+
10
+ <!-- Static code is written/imported inside 'q-item-container' (e.g. Header, Title components) -->
11
+ <div class="q-item-container">
12
+ {#if !displayOptions.hideTitle}
13
+ <Header title={item.title} />
14
+ {#if item.subtitle}
15
+ <div class="s-q-item__subtitle s-font-note">{item.subtitle}</div>
16
+ {/if}
17
+ {/if}
18
+ <!-- TODO: Rename 'q-your-tool-container' to 'q-<tool-name>-container' & change all references -->
19
+ <div id="{id}_container" class="q-your-tool-container" />
20
+ <Footer notes={item.notes} sources={item.sources} acronym={item.acronym} />
21
+ </div>
@@ -0,0 +1,31 @@
1
+ <script>
2
+ export let notes;
3
+ export let sources;
4
+ export let acronym;
5
+ </script>
6
+
7
+ <div class="s-q-item__footer">
8
+ {#if notes}
9
+ <div class="s-q-item__footer__notes">{notes}</div>
10
+ {/if}
11
+ <div class="s-q-item__footer__details">
12
+ {#if sources && sources.length > 0}
13
+ <div class="s-q-item__footer__sources">
14
+ {#if sources.length > 1}Quellen:{:else}Quelle:{/if}
15
+ {#each sources as source, index}
16
+ {#if source.text !== ""}
17
+ {#if source.link && source.link.url && source.link.isValid}<a
18
+ href={source.link.url}
19
+ target="blank"
20
+ rel="noopener noreferrer">{source.text}</a
21
+ >{:else}{source.text}{/if}{#if index !== sources.length - 1 && sources[index + 1] !== ""},&nbsp;{/if}{/if}
22
+ {/each}
23
+ </div>
24
+ {/if}
25
+ {#if acronym}
26
+ <div class="s-q-item__footer__acronym">NZZ / {acronym}</div>
27
+ {:else}
28
+ <div class="s-q-item__footer__acronym">NZZ</div>
29
+ {/if}
30
+ </div>
31
+ </div>
@@ -0,0 +1,7 @@
1
+ <script>
2
+ export let title;
3
+ </script>
4
+
5
+ <h3 class="s-q-item__title">
6
+ {title}
7
+ </h3>
@@ -1,4 +0,0 @@
1
- $color: purple;
2
- h1 {
3
- color: $color;
4
- }
@@ -1,98 +0,0 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const crypto = require("crypto");
4
-
5
- const sass = require("sass");
6
- const postcss = require("postcss");
7
- const postcssImport = require("postcss-import");
8
- const autoprefixer = require("autoprefixer");
9
- const cssnano = require("cssnano");
10
-
11
- const stylesDir = path.join(__dirname, "/../styles_src/");
12
-
13
- function writeHashmap(hashmapPath, files, fileext) {
14
- const hashMap = {};
15
- files
16
- .map(file => {
17
- const hash = crypto.createHash("md5");
18
- hash.update(file.content, { encoding: "utf8" });
19
- file.hash = hash.digest("hex");
20
- return file;
21
- })
22
- .map(file => {
23
- hashMap[file.name] = `${file.name}.${file.hash.substring(
24
- 0,
25
- 8
26
- )}.${fileext}`;
27
- });
28
-
29
- fs.writeFileSync(hashmapPath, JSON.stringify(hashMap));
30
- }
31
-
32
- async function compileStylesheet(name) {
33
- return new Promise((resolve, reject) => {
34
- const filePath = path.join(stylesDir, `${name}.scss`);
35
- fs.access(filePath, fs.constants.R_OK, err => {
36
- if (err) {
37
- reject(new Error(`stylesheet ${filePath} cannot be read`));
38
- process.exit(1);
39
- }
40
- sass.render(
41
- {
42
- file: filePath,
43
- outputStyle: "compressed"
44
- },
45
- (err, sassResult) => {
46
- if (err) {
47
- reject(err);
48
- } else {
49
- postcss()
50
- .use(postcssImport)
51
- .use(autoprefixer)
52
- .use(cssnano)
53
- .process(sassResult.css, {
54
- from: path.join(stylesDir, `${name}.css`)
55
- })
56
- .then(prefixedResult => {
57
- if (prefixedResult.warnings().length > 0) {
58
- console.log(`failed to compile stylesheet ${name}`);
59
- process.exit(1);
60
- }
61
- resolve(prefixedResult.css);
62
- });
63
- }
64
- }
65
- );
66
- });
67
- });
68
- }
69
-
70
- async function buildStyles() {
71
- try {
72
- // compile styles
73
- const styleFiles = [
74
- {
75
- name: "default",
76
- content: await compileStylesheet("default")
77
- }
78
- ];
79
-
80
- styleFiles.map(file => {
81
- fs.writeFileSync(`styles/${file.name}.css`, file.content);
82
- });
83
-
84
- writeHashmap("styles/hashMap.json", styleFiles, "css");
85
- } catch (err) {
86
- console.error(err);
87
- process.exit(1);
88
- }
89
- }
90
-
91
- Promise.all([buildStyles()])
92
- .then(res => {
93
- console.log("build complete");
94
- })
95
- .catch(err => {
96
- console.error(err.message);
97
- process.exit(1);
98
- });