Add style transforms (#7)

* Add style transforms

* Let crawler be sync
This commit is contained in:
Drew Powers 2021-03-18 11:25:19 -06:00 committed by GitHub
parent 48d73e3ab3
commit 5661b28914
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 370 additions and 55 deletions

230
package-lock.json generated
View file

@ -184,6 +184,15 @@
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
"dev": true
},
"@types/sass": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.16.0.tgz",
"integrity": "sha512-2XZovu4NwcqmtZtsBR5XYLw18T8cBCnU2USFHTnYLLHz9fkhnoEMoDsqShJIOFsFhn5aJHjweiUUdTrDGujegA==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/yargs-parser": {
"version": "20.2.0",
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz",
@ -460,7 +469,6 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
"dev": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@ -491,6 +499,19 @@
"resolved": "https://registry.npmjs.org/astring/-/astring-1.7.0.tgz",
"integrity": "sha512-43bervUZNvahG1v74a+POdGlAWcOUGSvP9fJVj6sywzM/SquwDkA+CdP938e8tWHUV77fStCiqzaQHAt0u6MVA=="
},
"autoprefixer": {
"version": "10.2.5",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.5.tgz",
"integrity": "sha512-7H4AJZXvSsn62SqZyJCP+1AWwOuoYpUfK6ot9vm0e87XD6mT8lDywc9D9OTJPMULyGcvmIxzTAMeG2Cc+YX+fA==",
"requires": {
"browserslist": "^4.16.3",
"caniuse-lite": "^1.0.30001196",
"colorette": "^1.2.2",
"fraction.js": "^4.0.13",
"normalize-range": "^0.1.2",
"postcss-value-parser": "^4.1.0"
}
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@ -502,11 +523,15 @@
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
},
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
},
"boolbase": {
"version": "1.0.0",
@ -551,11 +576,22 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"browserslist": {
"version": "4.16.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz",
"integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==",
"requires": {
"caniuse-lite": "^1.0.30001181",
"colorette": "^1.2.1",
"electron-to-chromium": "^1.3.649",
"escalade": "^3.1.1",
"node-releases": "^1.1.70"
}
},
"cacheable-request": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
@ -600,6 +636,11 @@
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
"caniuse-lite": {
"version": "1.0.30001202",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001202.tgz",
"integrity": "sha512-ZcijQNqrcF8JNLjzvEiXqX4JUYxoZa7Pvcsd9UD8Kz4TvhTonOSNRsK+qtvpVL4l6+T1Rh4LFtLfnNWg6BGWCQ=="
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
@ -710,7 +751,6 @@
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
"dev": true,
"requires": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
@ -794,8 +834,7 @@
"colorette": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
"dev": true
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w=="
},
"concat-map": {
"version": "0.0.1",
@ -935,6 +974,11 @@
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
},
"cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="
},
"csstype": {
"version": "2.6.16",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
@ -1072,12 +1116,22 @@
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.691",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.691.tgz",
"integrity": "sha512-ZqiO69KImmOGCyoH0icQPU3SndJiW93juEvf63gQngyhODO6SpQIPMTOHldtCs5DS5GMKvAkquk230E2zt2vpw=="
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@ -1123,8 +1177,7 @@
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"dev": true
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
},
"escape-goat": {
"version": "2.1.1",
@ -1447,7 +1500,6 @@
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
@ -1468,6 +1520,11 @@
"integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
"dev": true
},
"fraction.js": {
"version": "4.0.13",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz",
"integrity": "sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA=="
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -1491,6 +1548,14 @@
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
},
"generic-names": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz",
"integrity": "sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==",
"requires": {
"loader-utils": "^1.1.0"
}
},
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@ -1524,7 +1589,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
@ -1680,6 +1744,16 @@
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
"dev": true
},
"icss-replace-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
"integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0="
},
"icss-utils": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA=="
},
"ignore": {
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
@ -1714,6 +1788,11 @@
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true
},
"indexes-of": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
"integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -1759,7 +1838,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"requires": {
"binary-extensions": "^2.0.0"
}
@ -1799,8 +1877,7 @@
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
},
"is-fullwidth-code-point": {
"version": "3.0.0",
@ -1812,7 +1889,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
@ -1841,8 +1917,7 @@
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
},
"is-obj": {
"version": "2.0.0",
@ -1926,6 +2001,14 @@
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"requires": {
"minimist": "^1.2.0"
}
},
"keyv": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
@ -1970,6 +2053,16 @@
"integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
"dev": true
},
"loader-utils": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
"integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^1.0.1"
}
},
"locate-character": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-2.0.5.tgz",
@ -1990,6 +2083,11 @@
"resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz",
"integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU="
},
"lodash.camelcase": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
"integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
},
"lodash.defaults": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
@ -2186,8 +2284,7 @@
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"mkdirp": {
"version": "1.0.4",
@ -2203,8 +2300,7 @@
"nanoid": {
"version": "3.1.22",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz",
"integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==",
"dev": true
"integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ=="
},
"natural-compare": {
"version": "1.4.0",
@ -2212,6 +2308,11 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"node-releases": {
"version": "1.1.71",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz",
"integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg=="
},
"nodemon": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz",
@ -2275,8 +2376,12 @@
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
},
"normalize-range": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
"integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI="
},
"normalize-url": {
"version": "4.5.0",
@ -2420,8 +2525,7 @@
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
"dev": true
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
},
"pify": {
"version": "2.3.0",
@ -2432,13 +2536,74 @@
"version": "8.2.8",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.8.tgz",
"integrity": "sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw==",
"dev": true,
"requires": {
"colorette": "^1.2.2",
"nanoid": "^3.1.20",
"source-map": "^0.6.1"
}
},
"postcss-modules": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-4.0.0.tgz",
"integrity": "sha512-ghS/ovDzDqARm4Zj6L2ntadjyQMoyJmi0JkLlYtH2QFLrvNlxH5OAVRPWPeKilB0pY7SbuhO173KOWkPAxRJcw==",
"requires": {
"generic-names": "^2.0.1",
"icss-replace-symbols": "^1.1.0",
"lodash.camelcase": "^4.3.0",
"postcss-modules-extract-imports": "^3.0.0",
"postcss-modules-local-by-default": "^4.0.0",
"postcss-modules-scope": "^3.0.0",
"postcss-modules-values": "^4.0.0",
"string-hash": "^1.1.1"
}
},
"postcss-modules-extract-imports": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw=="
},
"postcss-modules-local-by-default": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz",
"integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==",
"requires": {
"icss-utils": "^5.0.0",
"postcss-selector-parser": "^6.0.2",
"postcss-value-parser": "^4.1.0"
}
},
"postcss-modules-scope": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
"integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
"requires": {
"postcss-selector-parser": "^6.0.4"
}
},
"postcss-modules-values": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
"integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
"requires": {
"icss-utils": "^5.0.0"
}
},
"postcss-selector-parser": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz",
"integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==",
"requires": {
"cssesc": "^3.0.0",
"indexes-of": "^1.0.1",
"uniq": "^1.0.1",
"util-deprecate": "^1.0.2"
}
},
"postcss-value-parser": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
},
"preact": {
"version": "10.5.12",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.5.12.tgz",
@ -2603,7 +2768,6 @@
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
"dev": true,
"requires": {
"picomatch": "^2.2.1"
}
@ -2718,7 +2882,6 @@
"version": "1.32.8",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.32.8.tgz",
"integrity": "sha512-Sl6mIeGpzjIUZqvKnKETfMf0iDAswD9TNlv13A7aAF3XZlRPMq4VvJWBC2N2DXbp94MQVdNSFG6LfF/iOXrPHQ==",
"dev": true,
"requires": {
"chokidar": ">=2.0.0 <4.0.0"
}
@ -2869,6 +3032,11 @@
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"string-hash": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz",
"integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs="
},
"string-width": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
@ -3044,7 +3212,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
@ -3135,6 +3302,11 @@
}
}
},
"uniq": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
},
"unique-string": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",

View file

@ -30,6 +30,7 @@
"acorn": "^7.4.0",
"acorn-jsx": "^5.3.1",
"astring": "^1.7.0",
"autoprefixer": "^10.2.5",
"cheerio": "^0.22.0",
"css-tree": "^1.1.2",
"domhandler": "^4.0.0",
@ -41,14 +42,18 @@
"magic-string": "^0.25.3",
"micromark": "^2.11.4",
"micromark-extension-gfm": "^0.3.3",
"postcss": "^8.2.8",
"postcss-modules": "^4.0.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"sass": "^1.32.8",
"snowpack": "^3.1.0-pre.13",
"svelte": "^3.35.0",
"vue": "^3.0.7",
"yargs-parser": "^20.2.7"
},
"devDependencies": {
"@types/sass": "^1.16.0",
"@types/yargs-parser": "^20.2.0",
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
@ -59,11 +64,9 @@
"eslint-plugin-prettier": "^3.3.1",
"estree-walker": "^3.0.0",
"nodemon": "^2.0.7",
"postcss": "^8.2.8",
"preact": "^10.5.12",
"preact-render-to-string": "^5.1.14",
"prettier": "^2.2.1",
"sass": "^1.32.8",
"typescript": "^4.2.3"
}
}

View file

@ -13,14 +13,15 @@ module.exports = function (snowpackConfig, { resolve } = {}) {
},
async load({ filePath }) {
const { compilePage, compileComponent } = await transformPromise;
const projectRoot = snowpackConfig.root;
const contents = await readFile(filePath, "utf-8");
if (!filePath.includes("/pages/") && !filePath.includes("/layouts/")) {
const result = await compileComponent(contents, filePath, { resolve });
const result = await compileComponent(contents, { compileOptions: { resolve }, filename: filePath, projectRoot });
return result.contents;
}
const result = await compilePage(contents, filePath, { resolve });
const result = await compilePage(contents, { compileOptions: { resolve }, filename: filePath, projectRoot });
try {
return /* js */ `

View file

@ -9,3 +9,8 @@ export interface AstroConfig {
projectRoot: URL;
hmxRoot: URL;
}
export interface JsxItem {
name: string;
jsx: string;
}

2
src/@types/postcss-modules.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
// dont need types; just a plugin
declare module 'postcss-modules';

92
src/style.ts Normal file
View file

@ -0,0 +1,92 @@
import crypto from 'crypto';
import path from 'path';
import autoprefixer from 'autoprefixer';
import postcss from 'postcss';
import postcssModules from 'postcss-modules';
import sass from 'sass';
type StyleType = 'text/css' | 'text/scss' | 'text/sass' | 'text/postcss';
const getStyleType: Map<string, StyleType> = new Map([
['.css', 'text/css'],
['.pcss', 'text/postcss'],
['.sass', 'text/sass'],
['.scss', 'text/scss'],
['css', 'text/css'],
['postcss', 'text/postcss'],
['sass', 'text/sass'],
['scss', 'text/scss'],
['text/css', 'text/css'],
['text/postcss', 'text/postcss'],
['text/sass', 'text/sass'],
['text/scss', 'text/scss'],
]);
const SASS_OPTIONS: Partial<sass.Options> = {
outputStyle: 'compressed',
};
/** Should be deterministic, given a unique filename */
function hashFromFilename(filename: string): string {
const hash = crypto.createHash('sha256');
return hash.update(filename.replace(/\\/g, '/')).digest('base64').toString().substr(0, 8);
}
export async function transformStyle(
code: string,
{ type, classNames, filename, fileID }: { type?: string; classNames?: Set<string>; filename: string; fileID: string }
): Promise<{ css: string; cssModules: Map<string, string> }> {
let styleType: StyleType = 'text/css'; // important: assume CSS as default
if (type) {
styleType = getStyleType.get(type) || styleType;
}
let css = '';
switch (styleType) {
case 'text/css': {
css = code;
break;
}
case 'text/sass':
case 'text/scss': {
css = sass
.renderSync({
...SASS_OPTIONS,
data: code,
includePaths: [path.dirname(filename)],
})
.css.toString('utf8');
break;
}
case 'text/postcss': {
css = code; // TODO
break;
}
default: {
throw new Error(`Unsupported: <style type="${styleType}">`);
}
}
const cssModules = new Map<string, string>();
css = await postcss([
postcssModules({
generateScopedName(name: string) {
if (classNames && classNames.has(name)) {
return `${name}__${hashFromFilename(fileID)}`;
}
return name;
},
getJSON(_: string, json: any) {
Object.entries(json).forEach(([k, v]: any) => {
if (k !== v) cssModules.set(k, v);
});
},
}),
autoprefixer(),
])
.process(css, { from: filename })
.then((result) => result.css);
return { css, cssModules };
}

View file

@ -12,6 +12,8 @@ import { parse } from './compiler/index.js';
import markdownEncode from './markdown-encode.js';
import { TemplateNode } from './compiler/interfaces.js';
import { defaultLogOptions, info } from './logger.js';
import { transformStyle } from './style.js';
import { JsxItem } from './@types/astro.js';
const { transformSync } = esbuild;
@ -30,7 +32,7 @@ interface CompileOptions {
const defaultCompileOptions: CompileOptions = {
logging: defaultLogOptions,
resolve: (p: string) => p
resolve: (p: string) => p,
};
function internalImport(internalPath: string) {
@ -179,11 +181,11 @@ function compileScriptSafe(raw: string, loader: 'jsx' | 'tsx'): string {
return code;
}
async function convertHmxToJsx(template: string, filename: string, compileOptions: CompileOptions) {
async function convertHmxToJsx(template: string, { compileOptions, filename, fileID }: { compileOptions: CompileOptions; filename: string; fileID: string }) {
await eslexer.init;
const ast = parse(template, {
filename
filename,
});
const script = compileScriptSafe(ast.instance ? ast.instance.content : '', 'tsx');
@ -201,11 +203,12 @@ async function convertHmxToJsx(template: string, filename: string, compileOption
);
const additionalImports = new Set<string>();
let items: { name: string; jsx: string }[] = [];
let items: JsxItem[] = [];
let mode: 'JSX' | 'SCRIPT' | 'SLOT' = 'JSX';
let collectionItem: { name: string; jsx: string } | undefined;
let collectionItem: JsxItem | undefined;
let currentItemName: string | undefined;
let currentDepth = 0;
const classNames: Set<string> = new Set();
walk(ast.html, {
enter(node, parent, prop, index) {
@ -249,6 +252,7 @@ async function convertHmxToJsx(template: string, filename: string, compileOption
if (!collectionItem) {
return;
}
break;
case 'InlineComponent':
case 'Element':
const name: string = node.name;
@ -263,6 +267,14 @@ async function convertHmxToJsx(template: string, filename: string, compileOption
collectionItem = { name, jsx: '' };
items.push(collectionItem);
}
if (attributes.class) {
attributes.class
.replace(/^"/, '')
.replace(/"$/, '')
.split(' ')
.map((c) => c.trim())
.forEach((c) => classNames.add(c));
}
collectionItem.jsx += collectionItem.jsx === '' ? '' : ',';
const COMPONENT_NAME_SCANNER = /^[A-Z]/;
if (!COMPONENT_NAME_SCANNER.test(name)) {
@ -282,6 +294,7 @@ async function convertHmxToJsx(template: string, filename: string, compileOption
if (wrapperImport) {
additionalImports.add(wrapperImport);
}
collectionItem.jsx += `h(${wrapper}, ${attributes ? generateAttributes(attributes) : 'null'}`;
return;
case 'Attribute': {
@ -347,13 +360,31 @@ async function convertHmxToJsx(template: string, filename: string, compileOption
},
});
/*
console.log({
additionalImports,
script,
items,
let stylesPromises: any[] = [];
walk(ast.css, {
enter(node) {
if (node.type !== 'Style') return;
const code = node.content.styles;
const typeAttr = node.attributes && node.attributes.find(({ name }) => name === 'type');
stylesPromises.push(
transformStyle(code, {
type: (typeAttr.value[0] && typeAttr.value[0].raw) || undefined,
classNames,
filename,
fileID,
})
); // TODO: styles needs to go in <head>
},
});
*/
const styles = await Promise.all(stylesPromises); // TODO: clean this up
console.log({ styles });
// console.log({
// additionalImports,
// script,
// items,
// });
return {
script: script + '\n' + Array.from(additionalImports).join('\n'),
@ -361,7 +392,7 @@ async function convertHmxToJsx(template: string, filename: string, compileOption
};
}
async function convertMdToJsx(contents: string, filename: string, compileOptions: CompileOptions) {
async function convertMdToJsx(contents: string, { compileOptions, filename, fileID }: { compileOptions: CompileOptions; filename: string; fileID: string }) {
// This doesn't work.
const { data: _frontmatterData, content } = matter(contents);
const mdHtml = micromark(content, {
@ -389,24 +420,30 @@ async function convertMdToJsx(contents: string, filename: string, compileOptions
`<script hmx="setup">export function setup() {
return ${JSON.stringify(setupData)};
}</script><head></head><body>${mdHtml}</body>`,
filename,
compileOptions
{ compileOptions, filename, fileID }
);
}
async function transformFromSource(contents: string, filename: string, compileOptions: CompileOptions): Promise<ReturnType<typeof convertHmxToJsx>> {
async function transformFromSource(
contents: string,
{ compileOptions, filename, projectRoot }: { compileOptions: CompileOptions; filename: string; projectRoot: string }
): Promise<ReturnType<typeof convertHmxToJsx>> {
const fileID = path.relative(projectRoot, filename);
switch (path.extname(filename)) {
case '.hmx':
return convertHmxToJsx(contents, filename, compileOptions);
return convertHmxToJsx(contents, { compileOptions, filename, fileID });
case '.md':
return convertMdToJsx(contents, filename, compileOptions);
return convertMdToJsx(contents, { compileOptions, filename, fileID });
default:
throw new Error('Not Supported!');
}
}
export async function compilePage(source: string, filename: string, opts: CompileOptions = defaultCompileOptions) {
const sourceJsx = await transformFromSource(source, filename, opts);
export async function compilePage(
source: string,
{ compileOptions = defaultCompileOptions, filename, projectRoot }: { compileOptions: CompileOptions; filename: string; projectRoot: string }
) {
const sourceJsx = await transformFromSource(source, { compileOptions, filename, projectRoot });
const headItem = sourceJsx.items.find((item) => item.name === 'head');
const bodyItem = sourceJsx.items.find((item) => item.name === 'body');
const headItemJsx = !headItem ? 'null' : headItem.jsx.replace('"head"', 'isRoot ? "head" : Fragment');
@ -425,8 +462,11 @@ export function body({title, description, props}, child, isRoot) { return (${bod
};
}
export async function compileComponent(source: string, filename: string, opts: CompileOptions = defaultCompileOptions) {
const sourceJsx = await transformFromSource(source, filename, opts);
export async function compileComponent(
source: string,
{ compileOptions = defaultCompileOptions, filename, projectRoot }: { compileOptions: CompileOptions; filename: string; projectRoot: string }
) {
const sourceJsx = await transformFromSource(source, { compileOptions, filename, projectRoot });
const componentJsx = sourceJsx.items.find((item) => item.name === 'Component');
if (!componentJsx) {
throw new Error(`${filename} <Component> expected!`);