「 一个有用的CSS片段的策划集合 」
Explanation
"version": "1.0.0"
虽然说-本次的项目主要是供给一些css有用的片段
但主要编写的还是一个-md
-网页-生成
本目录
"main": "index.js",
"scripts": {
"dev": "nodemon -e md,js ./scripts/build.js & parcel",
"build": "node ./scripts/build.js && npm run prettier && npm run parcel",
"parcel": "parcel build index.html -d docs/ --public-url ./",
"prettier": "prettier --single-quote --no-semi --print-width=100 ./js/index.js --write \"./src/**/*.js\" \"./src/**/*.scss\""
},
主要文件-index.js
npm run dev
nodemon 作为一个监控node.js应用程序中的任何更改并自动重启服务器
nodemon -e md,js ./scripts/build.js & parce
启动 build.js 文件 并 观察后缀md,js 文件自动重启
parcel
parcel
快速发展,零配置的Web应用程序捆绑器
parcel build index.html -d docs/ --public-url ./
构建以index.html
为头, 输出目录-docs/
关键网址路径为./
本目录
prettier
prettier
Prettier
是一个有见识的代码格式化工具。
prettier --single-quote --no-semi --print-width=100 ./js/index.js --write \"./src/**/*.js\" \"./src/**/*.scss\"
就是变漂亮, 有兴趣的看官网😊
build
集合前面所有
其实到这里我们可以发现有个未知功能的构建文件
./scripts/build.js
, 同时也是一切的开头-功能的文件
让我们看看它./scripts/build.js
做了什么
代码 1-6
const fs = require('fs')
const path = require('path')
const marked = require('marked')
const pretty = require('pretty')
const caniuseDb = require('caniuse-db/data.json')
const { toKebabCase, createElement, template, dom } = require('../utils/utils.js')
代码 8-30
const SNIPPETS_PATH = './snippets'
const TAGS = [
{
name: 'all',
icon: 'check'
},
{
name: 'layout',
icon: 'layout'
},
{
name: 'visual',
icon: 'eye'
},
{
name: 'animation',
icon: 'loader'
},
{
name: 'interactivity',
icon: 'edit-2'
}
]
markdown-解析器和编译器。为速度而建造 github-source>>
代码 32-42
const renderer = new marked.Renderer()
renderer.heading = (text, level) => {
if (level === 3) {
// markdown - ###
// 第一种情况
return `<h${level} id="${toKebabCase(text)}"><span>${text}</span></h${level}>`
} else {
// 第二
return ['HTML', 'CSS', 'JavaScript'].includes(text)
? `<h${level} data-type="${text}">${text}</h${level}>`
// 第三
: `<h${level}>${text}</h${level}>`
}
}
renderer.link = (url, _, text) => `<a href="${url}" target="_blank">${text || url}</a>`
- 3.1
renderer
从
marked.Renderer()
获得一个新对象
- 3.2
toKebabCase
剔除不正确字符-用
-
串联
- 3.3
renderer.heading
设置
###
转换命令, 有三种情况
3⃣️种情况-详解
第一种情况1⃣️
### Box-sizing reset
md ->
<h3 id="box-sizing-reset"><span>Box-sizing reset</span></h3>
html
第二2⃣️
#### Css
->
<h4 data-type="CSS">CSS</h4>
第三3⃣️
#### Demo
->
<h4>Demo</h4>
-
- 3.4
renderer.link
设置-url
* https://caniuse.com/#feat=text-overflow
md ->
<a href="https://caniuse.com/#feat=text-overflow" target="_blank">https://caniuse.com/#feat=text-overflow</a>
html
const document = dom('./src/html/index.html')
const components = {
backToTopButton: dom('./src/html/components/back-to-top-button.html'),
sidebar: dom('./src/html/components/sidebar.html'),
header: dom('./src/html/components/header.html'),
main: dom('./src/html/components/main.html'),
tags: dom('./src/html/components/tags.html')
}
用 JSDOM 给出 浏览器api
const snippetContainer = components.main.querySelector('.container')
const sidebarLinkContainer = components.sidebar.querySelector('.sidebar__links')
TAGS.slice(1).forEach(tag => {
sidebarLinkContainer.append(
createElement(`
<section data-type="${tag.name}" class="sidebar__section">
<h4 class="sidebar__section-heading">${tag.name}</h4>
</section>
`)
)
})
for (const snippetFile of fs.readdirSync(SNIPPETS_PATH)) { // 拿到-讲解-css-md 文件
const snippetPath = path.join(SNIPPETS_PATH, snippetFile) // 路径
const snippetData = fs.readFileSync(snippetPath, 'utf8') // 数据
const markdown = marked(snippetData, { renderer }) // 解析 md -> html
const snippetEl = createElement(`<div class="snippet">${markdown}</div>`) // 放入 html 元素
snippetContainer.append(snippetEl) // 再 放入 html 元素
// browser support usage 浏览器支持-情况
const featUsageShares = (snippetData.match(/https?:\/\/caniuse\.com\/#feat=.*/g) || []).map(
feat => {
const featData = caniuseDb.data[feat.match(/#feat=(.*)/)[1]]
return featData ? Number(featData.usage_perc_y + featData.usage_perc_a) : 100
}
)
const browserSupportHeading = snippetEl.querySelector('h4:last-of-type')
browserSupportHeading.after(
createElement(`
<div>
<div class="snippet__browser-support">
${featUsageShares.length ? Math.min(...featUsageShares).toPrecision(3) : '99+'}%
</div>
</div>
`)
)
// sidebar link 侧边-css-超链接
const link = createElement(
`<a class="sidebar__link" href="#${snippetFile.replace('.md', '')}">${
snippetEl.querySelector('h3').innerHTML
}</a>`
)
// tags css-讲解-html的小标签
const tags = (snippetData.match(/<!--\s*tags:\s*(.+?)-->/) || [, ''])[1]
.split(/,\s*/)
.forEach(tag => {
tag = tag.trim().toLowerCase()
snippetEl
.querySelector('h3')
.append(
createElement(
`<span class="tags__tag snippet__tag" data-type="${tag}"><i data-feather="${
TAGS.find(t => t.name === tag).icon
}"></i>${tag}</span>`
)
)
sidebarLinkContainer.querySelector(`section[data-type="${tag}"]`).append(link)
})
}
// build dom
TAGS.forEach(tag =>
components.tags.append(
createElement(
`<button class="tags__tag is-large ${tag.name === 'all' ? 'is-active' : ''}" data-type="${
tag.name
}"><i data-feather="${tag.icon}"></i>${tag.name}</button>`
)
)
)
const content = document.querySelector('.content-wrapper')
content.before(components.backToTopButton)
content.before(components.sidebar)
content.append(components.header)
content.append(components.main)
components.main.querySelector('.container').prepend(components.tags)
// doctype declaration gets stripped, add it back in
const html = `<!DOCTYPE html>
${pretty(document.documentElement.outerHTML, { ocd: true })}
`
fs.writeFileSync('./index.html', html)
const fs = require('fs')
const { JSDOM } = require('jsdom')
exports.toKebabCase = str =>
str &&
str
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
.map(x => x.toLowerCase())
.join('-')
变小写 同时 将 类似 字段含有空格「HELLO World」 => 变 => 「hello-world」
exports.dom = path => {
const doc = new JSDOM(fs.readFileSync(path, 'utf8')).window.document
return path.includes('component') ? doc.body.firstElementChild : doc
}
JSDOM
可以提供 浏览器的api, 用户像在浏览器体验
这里是 返回 主document
exports.createElement = str => {
const el = new JSDOM().window.document.createElement('div')
el.innerHTML = str
return el.firstElementChild
}
JSDOM
可以提供 浏览器的api, 用户像在浏览器体验
这里是返回 html element