refactor project structures
- vite.config.js: used to generate static cv in a single html file - vite.config.site.js: used to build the jsoncv site, including editor and preview pages
This commit is contained in:
parent
aa2ac69904
commit
6461995fbf
|
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>CV</title>
|
||||||
|
<link rel="stylesheet" href="/src/scss/print.css">
|
||||||
|
<link rel="stylesheet" href="/src/themes/<%= theme %>/index.scss">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="cv-container">
|
||||||
|
<%- include('src/themes/' + theme + '/index', locals) %>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -5,7 +5,10 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host",
|
"dev": "vite --host",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"dev-site": "vite -c vite.config.site.js --host",
|
||||||
|
"build-site": "vite -c vite.config.site.js build",
|
||||||
|
"preview-site": "vite -c vite.config.site.js preview"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify-json/mdi": "^1.1.33",
|
"@iconify-json/mdi": "^1.1.33",
|
||||||
|
|
@ -14,8 +17,9 @@
|
||||||
"rollup-plugin-node-polyfills": "^0.2.1",
|
"rollup-plugin-node-polyfills": "^0.2.1",
|
||||||
"sass": "^1.54.8",
|
"sass": "^1.54.8",
|
||||||
"vite": "^4.1.1",
|
"vite": "^4.1.1",
|
||||||
|
"vite-plugin-ejs": "^1.6.4",
|
||||||
"vite-plugin-handlebars": "^1.6.0",
|
"vite-plugin-handlebars": "^1.6.0",
|
||||||
"vite-plugin-node-polyfills": "^0.7.0"
|
"vite-plugin-singlefile": "^0.13.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify/json": "^2.2.15",
|
"@iconify/json": "^2.2.15",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>JSONCV Editor</title>
|
<title>JSONCV Editor</title>
|
||||||
<link rel="stylesheet" href="styles.scss" />
|
<link rel="stylesheet" href="../scss/styles.scss" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="main">
|
<div id="main">
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
<div class="middle column editor-container"></div>
|
<div class="middle column editor-container"></div>
|
||||||
<div class="right column">
|
<div class="right column">
|
||||||
<div class="output-json code-block" style="display: none;"></div>
|
<div class="output-json code-block" style="display: none;"></div>
|
||||||
<iframe class="output-html" src="/editor/preview.html" frameborder="0"></iframe>
|
<iframe class="output-html" src="/preview/" frameborder="0"></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import objectPath from 'object-path';
|
||||||
import { JSONEditor } from '@json-editor/json-editor/dist/jsoneditor';
|
import { JSONEditor } from '@json-editor/json-editor/dist/jsoneditor';
|
||||||
|
|
||||||
import * as sampleModule from '../../sample.resume.json';
|
import * as sampleModule from '../../sample.resume.json';
|
||||||
|
import * as jsoncvSchemaModule from '../../schema/jsoncv.schema.json';
|
||||||
import {
|
import {
|
||||||
getCVData,
|
getCVData,
|
||||||
saveCVJSON,
|
saveCVJSON,
|
||||||
|
|
@ -18,9 +19,8 @@ import {
|
||||||
propertiesToObject,
|
propertiesToObject,
|
||||||
traverseDownObject,
|
traverseDownObject,
|
||||||
} from '../lib/utils';
|
} from '../lib/utils';
|
||||||
import * as jsoncvSchemaModule from '../schema/jsoncv.schema.json';
|
import { registerIconLib } from './je-iconlib';
|
||||||
import { registerIconLib } from './iconlib';
|
import { registerTheme } from './je-theme';
|
||||||
import { registerTheme } from './theme';
|
|
||||||
|
|
||||||
const propertiesInOrder = ['basics', 'education', 'work', 'skills', 'projects', 'sideProjects', 'languages', 'interests', 'references', 'awards', 'publications', 'volunteer', 'meta']
|
const propertiesInOrder = ['basics', 'education', 'work', 'skills', 'projects', 'sideProjects', 'languages', 'interests', 'references', 'awards', 'publications', 'volunteer', 'meta']
|
||||||
const basicsPropertiesInOrder = ['name', 'label', 'email', 'phone', 'url', 'summary', 'image', 'location', 'profiles']
|
const basicsPropertiesInOrder = ['name', 'label', 'email', 'phone', 'url', 'summary', 'image', 'location', 'profiles']
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,12 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>CV</title>
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="cv-container"></div>
|
<div>JSONCV</div>
|
||||||
|
<a href="/editor/">Editor</a>
|
||||||
<script src="main.js" type="module"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This plugin allows for importing ejs files as strings.
|
||||||
|
*
|
||||||
|
* ref 1: https://vitejs.dev/guide/api-plugin.html#transforming-custom-file-types
|
||||||
|
* ref 2: https://github.com/vitejs/vite/issues/594#issuecomment-665915643
|
||||||
|
*/
|
||||||
|
export function TransformEjs() {
|
||||||
|
return {
|
||||||
|
name: 'transform-ejs',
|
||||||
|
|
||||||
|
transform(src, id) {
|
||||||
|
if (id.endsWith('.ejs')) {
|
||||||
|
return {
|
||||||
|
code: `export default ${JSON.stringify(src)}`,
|
||||||
|
map: null, // provide source map if available
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
import './print.css';
|
|
||||||
|
|
||||||
import * as exampleData from '../data/rxresume-mengxiao.converted.json';
|
|
||||||
import { applyThemeTo } from './themer';
|
|
||||||
|
|
||||||
const elCV = document.querySelector('.cv-container')
|
|
||||||
|
|
||||||
|
|
||||||
applyThemeTo('default', elCV, exampleData)
|
|
||||||
|
|
@ -7,6 +7,6 @@
|
||||||
<body>
|
<body>
|
||||||
<div class="cv-container"></div>
|
<div class="cv-container"></div>
|
||||||
|
|
||||||
<script src="preview.js" type="module"></script>
|
<script src="main.js" type="module"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import '../print.css';
|
import '../scss/print.css';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getCVData,
|
getCVData,
|
||||||
getCVSavedTime,
|
getCVSavedTime,
|
||||||
} from '../lib/store';
|
} from '../lib/store';
|
||||||
import { applyThemeTo } from '../themer';
|
import { applyThemeTo } from '../themes';
|
||||||
|
|
||||||
const themeName = 'default'
|
const themeName = 'default'
|
||||||
const elCV = document.querySelector('.cv-container')
|
const elCV = document.querySelector('.cv-container')
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { reformatDate } from '../lib/date';
|
||||||
|
import { getIconSVG } from '../lib/icons';
|
||||||
|
|
||||||
|
export function getRenderData(cvData) {
|
||||||
|
return {
|
||||||
|
cv: cvData,
|
||||||
|
fn: {
|
||||||
|
reformatDate,
|
||||||
|
getIconSVG,
|
||||||
|
urlNoSchema,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fn */
|
||||||
|
|
||||||
|
function urlNoSchema(url) {
|
||||||
|
return url.replace(/https?:\/\//, '')
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import ejs from 'ejs';
|
import ejs from 'ejs';
|
||||||
|
|
||||||
import { reformatDate } from '../lib/date';
|
import { getRenderData } from './data';
|
||||||
import { getIconSVG } from '../lib/icons';
|
|
||||||
|
|
||||||
const themes = {}
|
const themes = {}
|
||||||
|
|
||||||
|
|
@ -10,13 +9,13 @@ const themeNames = ['reorx']
|
||||||
// https://vitejs.dev/guide/features.html#disabling-css-injection-into-the-page
|
// https://vitejs.dev/guide/features.html#disabling-css-injection-into-the-page
|
||||||
// note that `?raw` (https://vitejs.dev/guide/assets.html#importing-asset-as-string)
|
// note that `?raw` (https://vitejs.dev/guide/assets.html#importing-asset-as-string)
|
||||||
// cannot be used because we need vite to transform scss into css
|
// cannot be used because we need vite to transform scss into css
|
||||||
const styleMoudules = import.meta.glob("../templates/*/index.scss", { "query": "?inline" })
|
const styleMoudules = import.meta.glob("./*/index.scss", { "query": "?inline" })
|
||||||
|
|
||||||
for (const name of themeNames) {
|
for (const name of themeNames) {
|
||||||
const templateModule = await import(`../templates/${name}/index.ejs`)
|
const templateModule = await import(`./${name}/index.ejs`)
|
||||||
|
|
||||||
// https://vitejs.dev/guide/features.html#glob-import
|
// https://vitejs.dev/guide/features.html#glob-import
|
||||||
const styleModule = await styleMoudules[`../templates/${name}/index.scss`]()
|
const styleModule = await styleMoudules[`./${name}/index.scss`]()
|
||||||
|
|
||||||
themes[name] = {
|
themes[name] = {
|
||||||
template: templateModule.default,
|
template: templateModule.default,
|
||||||
|
|
@ -31,15 +30,8 @@ export function getTheme(name) {
|
||||||
return themes[name]
|
return themes[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderTheme(template, data, options) {
|
export function renderTheme(template, cvData, options) {
|
||||||
return ejs.render(template, {
|
return ejs.render(template, getRenderData(cvData), options)
|
||||||
cv: data,
|
|
||||||
fn: {
|
|
||||||
reformatDate,
|
|
||||||
getIconSVG,
|
|
||||||
urlNoSchema,
|
|
||||||
}
|
|
||||||
}, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const cvStyleId = 'cv-style'
|
const cvStyleId = 'cv-style'
|
||||||
|
|
@ -55,9 +47,3 @@ export function applyThemeTo(name, el, data) {
|
||||||
}
|
}
|
||||||
elStyle.innerHTML = theme.style
|
elStyle.innerHTML = theme.style
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fn */
|
|
||||||
|
|
||||||
function urlNoSchema(url) {
|
|
||||||
return url.replace(/https?:\/\//, '')
|
|
||||||
}
|
|
||||||
|
|
@ -19,7 +19,7 @@ $color-text-dim: #777;
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin: .8em 0 .2em 0;
|
margin: .2em 0 .2em 0;
|
||||||
}
|
}
|
||||||
.label {
|
.label {
|
||||||
margin: .4em 0;
|
margin: .4em 0;
|
||||||
|
|
@ -1,50 +1,21 @@
|
||||||
import { resolve } from 'path';
|
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
|
import { ViteEjsPlugin } from 'vite-plugin-ejs';
|
||||||
|
import { viteSingleFile } from 'vite-plugin-singlefile';
|
||||||
|
|
||||||
const sampleFilename = './sample.resume.json'
|
import { TransformEjs } from './src/lib/vite-plugins';
|
||||||
let dataFilename = process.env.DATA_FILENAME || sampleFilename
|
import { getRenderData } from './src/themes/data';
|
||||||
|
|
||||||
const data = require(dataFilename)
|
const dataFilename = process.env.DATA_FILENAME || './sample.resume.json'
|
||||||
|
const outDir = process.env.OUT_DIR || 'dist'
|
||||||
|
|
||||||
const rootDir = resolve(__dirname, 'src')
|
const cvData = require(dataFilename)
|
||||||
|
const data = getRenderData(cvData)
|
||||||
const fileRegex = /\.(my-file-ext)$/
|
data.theme = process.env.THEME || 'reorx'
|
||||||
|
|
||||||
// ref 1: https://vitejs.dev/guide/api-plugin.html#transforming-custom-file-types
|
|
||||||
// ref 2: https://github.com/vitejs/vite/issues/594#issuecomment-665915643
|
|
||||||
function TransformEjs() {
|
|
||||||
return {
|
|
||||||
name: 'transform-ejs',
|
|
||||||
|
|
||||||
transform(src, id) {
|
|
||||||
if (id.endsWith('.ejs')) {
|
|
||||||
return {
|
|
||||||
code: `export default ${JSON.stringify(src)}`,
|
|
||||||
map: null, // provide source map if available
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// use relative path for assets
|
|
||||||
// base: "",
|
|
||||||
root: 'src',
|
|
||||||
// assetsInclude: ['**/*.ejs'],
|
|
||||||
build: {
|
build: {
|
||||||
// relative to root
|
outDir: outDir,
|
||||||
outDir: "../dist",
|
|
||||||
// put assets in the same folder as index.html
|
|
||||||
// assetsDir: ".",
|
|
||||||
rollupOptions: {
|
|
||||||
input: {
|
|
||||||
main: resolve(rootDir, 'index.html'),
|
|
||||||
editor: resolve(rootDir, 'editor/index.html'),
|
|
||||||
editorPreview: resolve(rootDir, 'editor/preview.html'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
|
@ -54,5 +25,15 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
TransformEjs(),
|
TransformEjs(),
|
||||||
|
ViteEjsPlugin(
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
ejs: (viteConfig) => ({
|
||||||
|
// ejs options goes here.
|
||||||
|
views: [__dirname],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
),
|
||||||
|
viteSingleFile(),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
import { TransformEjs } from './src/lib/vite-plugins';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
root: 'src',
|
||||||
|
build: {
|
||||||
|
// allows 'import.meta.glob' to work
|
||||||
|
target: 'esnext',
|
||||||
|
rollupOptions: {
|
||||||
|
input: {
|
||||||
|
main: 'index.html',
|
||||||
|
editor: 'editor/index.html',
|
||||||
|
preview: 'preview/index.html',
|
||||||
|
// main: resolve(rootDir, 'index.html'),
|
||||||
|
// editor: resolve(rootDir, 'editor/index.html'),
|
||||||
|
// editorPreview: resolve(rootDir, 'editor/preview.html'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
// remove the "Module "fs" has been externalized" warning for ejs
|
||||||
|
'fs': 'src/lib/fs-polyfill.js',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
TransformEjs(),
|
||||||
|
],
|
||||||
|
})
|
||||||
Loading…
Reference in New Issue