diff --git a/.gitignore b/.gitignore index 5744b095c..12a422c4e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ node_modules docs/dist test/coverage packages/vant-css/build -packages/vant-css/icons +packages/icon/svg diff --git a/build/bin/build-changelog.sh b/build/build-changelog.sh similarity index 91% rename from build/bin/build-changelog.sh rename to build/build-changelog.sh index a4ef6d3da..e2b5c49a0 100644 --- a/build/bin/build-changelog.sh +++ b/build/build-changelog.sh @@ -19,4 +19,4 @@ github_changelog_generator \ --no-unreleased \ --max-issues 200 \ --since-tag v1.0.0 \ - -o $basepath/../../docs/markdown/changelog.generated.md + -o $basepath/../docs/markdown/changelog.generated.md diff --git a/build/bin/build-components.js b/build/build-components.js similarity index 77% rename from build/bin/build-components.js rename to build/build-components.js index 7725edcc2..b9d2ef1fe 100644 --- a/build/bin/build-components.js +++ b/build/build-components.js @@ -3,17 +3,19 @@ */ const fs = require('fs-extra'); const path = require('path'); -const compiler = require('vue-sfc-compiler'); -const esDir = path.join(__dirname, '../../es'); -const libDir = path.join(__dirname, '../../lib'); -const srcDir = path.join(__dirname, '../../packages'); const babel = require('babel-core'); +const compiler = require('vue-sfc-compiler'); + +const esDir = path.join(__dirname, '../es'); +const libDir = path.join(__dirname, '../lib'); +const srcDir = path.join(__dirname, '../packages'); const compilerOption = { babel: { - extends: path.join(__dirname, '../../.babelrc') + extends: path.join(__dirname, '../.babelrc') } }; -const whiteList = ['vant-css', 'test', 'demo']; + +const whiteList = /(demo|vant-css|test|\.md)$/; // clear dir fs.emptyDirSync(esDir); @@ -30,13 +32,13 @@ function compile(dir, jsOnly = false) { files.forEach(file => { const absolutePath = path.join(dir, file); - // 移除不需要的文件 - if (whiteList.indexOf(file) !== -1) { + // reomve unnecessary files + if (whiteList.test(file)) { fs.removeSync(absolutePath); - // 遍历文件夹 + // scan dir } else if (isDir(absolutePath)) { return compile(absolutePath); - // 编译 .vue 文件 + // compile sfc } else if (/\.vue$/.test(file) && !jsOnly) { const source = fs.readFileSync(absolutePath, 'utf-8'); fs.removeSync(absolutePath); @@ -54,6 +56,7 @@ function compile(dir, jsOnly = false) { } process.env.BABEL_ENV = 'commonjs'; + fs.copySync(esDir, libDir); compile(libDir); diff --git a/build/bin/build-entry.js b/build/build-entry.js similarity index 86% rename from build/bin/build-entry.js rename to build/build-entry.js index 2df46ff9f..7c6d0a507 100644 --- a/build/bin/build-entry.js +++ b/build/build-entry.js @@ -1,11 +1,11 @@ -const Components = require('./get-components')(); const fs = require('fs-extra'); const glob = require('fast-glob'); const path = require('path'); const uppercamelize = require('uppercamelcase'); -const version = process.env.VERSION || require('../../package.json').version; -const tips = '// This file is auto gererated by build/bin/build-entry.js'; -const root = path.join(__dirname, '../../'); +const Components = require('./get-components')(); +const version = process.env.VERSION || require('../package.json').version; +const tips = '// This file is auto gererated by build/build-entry.js'; +const root = path.join(__dirname, '../'); const join = dir => path.join(root, dir); function buildVantEntry() { @@ -48,11 +48,11 @@ export default { }; `; - fs.writeFileSync(path.join(__dirname, '../../packages/index.js'), content); + fs.writeFileSync(path.join(__dirname, '../packages/index.js'), content); } function buildDemoEntry() { - const dir = path.join(__dirname, '../../packages'); + const dir = path.join(__dirname, '../packages'); const demos = fs.readdirSync(dir) .filter(name => fs.existsSync(path.join(dir, `${name}/demo/index.vue`))) .map(name => `'${name}': () => wrapper(import('../../packages/${name}/demo'), '${name}')`); diff --git a/build/build-iconfont.js b/build/build-iconfont.js new file mode 100644 index 000000000..3f21b53f9 --- /dev/null +++ b/build/build-iconfont.js @@ -0,0 +1,79 @@ +/** + * build iconfont from sketch + */ +const fs = require('fs-extra'); +const gulp = require('gulp'); +const path = require('path'); +const glob = require('fast-glob'); +const shell = require('shelljs'); +const md5File = require('md5-file'); +const iconfont = require('gulp-iconfont'); +const iconfontCss = require('gulp-iconfont-css'); +const config = require('../packages/icon/config'); +const local = require('../packages/icon/config/template-local'); + +const iconDir = path.join(__dirname, '../packages/icon'); +const cssDir = path.join(__dirname, '../packages/vant-css/src'); +const svgDir = path.join(iconDir, 'svg'); +const sketch = path.join(iconDir, 'assert/icons.sketch'); +const template = path.join(iconDir, 'config/template.css'); + +// get md5 from sketch +const md5 = md5File.sync(sketch).slice(0, 6); +const ttf = `${config.name}-${md5}.ttf`; + +// extract svg from sketch +// should install sketchtool first +// install guide: https://developer.sketchapp.com/guides/sketchtool/ +shell.exec( + `sketchtool export slices --formats=svg --overwriting=YES --save-for-web=YES --output=${svgDir} ${sketch}` +); + +// remove previous ttf +const prevTTFs = glob.sync(path.join(iconDir, '*.ttf')); +prevTTFs.forEach(ttf => fs.removeSync(ttf)); + +// rename svg +config.glyphs.forEach((icon, index) => { + const src = path.join(svgDir, icon.src); + if (fs.existsSync(src)) { + fs.renameSync(src, path.join(svgDir, icon.css + '.svg')); + } +}); + +// generate ttf from sketch && build icon.css +gulp.task('ttf', () => { + return gulp + .src([`${svgDir}/*.svg`]) + .pipe( + iconfontCss({ + fontName: config.name, + path: template, + targetPath: '../vant-css/src/icon.css', + normalize: true, + firstGlyph: 0xf000, + cssClass: ttf // this is a trick to pass ttf to template + }) + ) + .pipe( + iconfont({ + fontName: ttf.replace('.ttf', ''), + formats: ['ttf'] + }) + ) + .pipe(gulp.dest(iconDir)); +}); + +gulp.task('default', ['ttf'], () => { + // generate icon-local.css + fs.writeFileSync( + path.join(cssDir, 'icon-local.css'), + local(config.name, ttf) + ); + + // remove svg + fs.removeSync(svgDir); + + // upload ttf to cdn + shell.exec(`superman cdn /vant ${path.join(iconDir, ttf)}`); +}); diff --git a/build/bin/build-lib.js b/build/build-lib.js similarity index 77% rename from build/bin/build-lib.js rename to build/build-lib.js index 8197c2b03..af11f5aa6 100644 --- a/build/bin/build-lib.js +++ b/build/build-lib.js @@ -1,7 +1,7 @@ /** * Build npm lib */ -require('shelljs/global'); +const shell = require('shelljs'); const signale = require('signale'); const tasks = [ 'lint', @@ -14,6 +14,6 @@ const tasks = [ tasks.forEach(task => { signale.pending(task); - exec(`npm run ${task} --silent`); + shell.exec(`npm run ${task} --silent`); signale.success(task); }); diff --git a/build/bin/build-style-entry.js b/build/build-style-entry.js similarity index 90% rename from build/bin/build-style-entry.js rename to build/build-style-entry.js index ddf9e5ae2..cc373d44a 100644 --- a/build/bin/build-style-entry.js +++ b/build/build-style-entry.js @@ -9,7 +9,7 @@ const dependencyTree = require('dependency-tree'); const SEP = path.sep; function build(folder, isESModule) { - const dir = path.resolve(__dirname, '../../', folder); + const dir = path.resolve(__dirname, '../', folder); components.forEach(componentName => { const content = analyzeDependencies(componentName, dir) .map(component => isESModule ? `import '../../vant-css/${component}.css';` : `require('../../vant-css/${component}.css');`); @@ -39,7 +39,7 @@ function build(folder, isESModule) { } function checkComponentHasStyle(componentName) { - return fs.existsSync(path.join(__dirname, `../../${folder}/vant-css/`, `${componentName}.css`)); + return fs.existsSync(path.join(__dirname, `../${folder}/vant-css/`, `${componentName}.css`)); } } diff --git a/build/bin/get-components.js b/build/get-components.js similarity index 75% rename from build/bin/get-components.js rename to build/get-components.js index b6857cc53..62a7483a4 100644 --- a/build/bin/get-components.js +++ b/build/get-components.js @@ -2,7 +2,7 @@ const fs = require('fs'); const path = require('path'); module.exports = function() { - const dirs = fs.readdirSync(path.resolve(__dirname, '../../packages')); + const dirs = fs.readdirSync(path.resolve(__dirname, '../packages')); const excludes = ['index.js', 'vant-css', 'mixins', 'utils', '.DS_Store']; return dirs.filter(dirName => excludes.indexOf(dirName) === -1); }; diff --git a/packages/vant-css/assets/Logo.sketch b/docs/src/asserts/Logo.sketch similarity index 100% rename from packages/vant-css/assets/Logo.sketch rename to docs/src/asserts/Logo.sketch diff --git a/docs/src/demo-entry.js b/docs/src/demo-entry.js index 73bfaf537..5c47b592e 100644 --- a/docs/src/demo-entry.js +++ b/docs/src/demo-entry.js @@ -1,4 +1,4 @@ -// This file is auto gererated by build/bin/build-entry.js +// This file is auto gererated by build/build-entry.js import { wrapper } from './demo-common'; export default { diff --git a/docs/src/docs-entry.js b/docs/src/docs-entry.js index 832dcb427..94af8e3d4 100644 --- a/docs/src/docs-entry.js +++ b/docs/src/docs-entry.js @@ -1,4 +1,4 @@ -// This file is auto gererated by build/bin/build-entry.js +// This file is auto gererated by build/build-entry.js export default { 'changelog.en-US': () => import('../markdown/changelog.en-US.md'), 'changelog.generated': () => import('../markdown/changelog.generated.md'), diff --git a/docs/src/mobile.js b/docs/src/mobile.js index 73f77c000..166932aa2 100644 --- a/docs/src/mobile.js +++ b/docs/src/mobile.js @@ -4,7 +4,6 @@ import App from './WapApp'; import routes from './router'; import progress from 'nprogress'; import '../../packages/vant-css/src/index.css'; -import '../../packages/vant-css/src/icon-local.css'; import 'vant-doc/src/helper/touch-simulator'; import './components/nprogress.css'; diff --git a/package.json b/package.json index 0ca633e2e..81c248072 100644 --- a/package.json +++ b/package.json @@ -15,15 +15,16 @@ "scripts": { "bootstrap": "yarn || npm i && cd ./packages/vant-css/ && yarn || npm i && cd ../../", "dev": "npm run build:file && webpack-serve --config build/webpack.dev.js", - "build:file": "node build/bin/build-entry.js", - "build:components": "node build/bin/build-components.js --color", + "lint": "./node_modules/.bin/eslint ./packages --ext .js,.vue", + "build:file": "node build/build-entry.js", + "build:components": "node build/build-components.js --color", "build:vant-css": "gulp build --gulpfile packages/vant-css/gulpfile.js --color", "build:vant": "cross-env NODE_ENV=production webpack --color --config build/webpack.build.js && cross-env NODE_ENV=production webpack -p --color --config build/webpack.build.js", - "build:style-entry": "node build/bin/build-style-entry.js", - "build:changelog": "sh build/bin/build-changelog.sh", - "deploy": "rimraf docs/dist && cross-env NODE_ENV=production webpack --config build/webpack.doc.js && gh-pages -d docs/dist", - "dist": "npm run bootstrap && node build/bin/build-lib.js", - "lint": "./node_modules/.bin/eslint ./packages --ext .js,.vue", + "build:style-entry": "node build/build-style-entry.js", + "build:changelog": "sh build/build-changelog.sh", + "build:iconfont": "gulp --gulpfile ./build/build-iconfont.js", + "build:lib": "npm run bootstrap && node build/build-lib.js", + "build:site": "rimraf docs/dist && cross-env NODE_ENV=production webpack --config build/webpack.doc.js && gh-pages -d docs/dist", "test": "jest", "test:watch": "jest --watch", "test:coverage": "open test/coverage/index.html", @@ -74,11 +75,15 @@ "fast-glob": "^2.2.2", "fast-vue-md-loader": "^1.0.3", "gh-pages": "^1.2.0", + "gulp": "^3.9.1", + "gulp-iconfont": "^9.2.0", + "gulp-iconfont-css": "^2.1.0", "html-webpack-plugin": "3.2.0", "husky": "^0.14.3", "jest": "^23.1.0", "jest-serializer-vue": "^2.0.2", "lint-staged": "^7.1.3", + "md5-file": "^4.0.0", "postcss": "^6.0.22", "postcss-calc": "^6.0.0", "postcss-easy-import": "^3.0.0", diff --git a/packages/vant-css/assets/icons.sketch b/packages/icon/assert/icons.sketch similarity index 100% rename from packages/vant-css/assets/icons.sketch rename to packages/icon/assert/icons.sketch diff --git a/packages/vant-css/scripts/icon-config.js b/packages/icon/config/index.js similarity index 100% rename from packages/vant-css/scripts/icon-config.js rename to packages/icon/config/index.js diff --git a/packages/vant-css/scripts/icon-local-template.js b/packages/icon/config/template-local.js similarity index 51% rename from packages/vant-css/scripts/icon-local-template.js rename to packages/icon/config/template-local.js index 83c9098ab..c589ec0fa 100644 --- a/packages/vant-css/scripts/icon-local-template.js +++ b/packages/icon/config/template-local.js @@ -1,8 +1,8 @@ -module.exports = (fontName, hash) => { +module.exports = (fontName, ttf) => { return `@font-face { font-style: normal; font-weight: normal; font-family: '${fontName}'; - src: url('./${fontName}-${hash}.ttf') format('truetype'); + src: url('../icon/${ttf}') format('truetype'); }`; }; diff --git a/packages/vant-css/scripts/icon-template.css b/packages/icon/config/template.css similarity index 81% rename from packages/vant-css/scripts/icon-template.css rename to packages/icon/config/template.css index 6c6aa9394..ede58054f 100644 --- a/packages/vant-css/scripts/icon-template.css +++ b/packages/icon/config/template.css @@ -4,7 +4,7 @@ font-style: normal; font-weight: normal; font-family: '<%= fontName %>'; - src: url('https://img.yzcdn.cn/zanui/icon/<%= fontName %>.ttf') format('truetype'); + src: url('https://img.yzcdn.cn/vant/<%= cssClass %>') format('truetype'); } .van-icon { @@ -36,7 +36,7 @@ } } -<% _.each(glyphs, function(glyph) { %>.van-<%= cssClass %>-<%= glyph.fileName %>:before { +<% _.each(glyphs, function(glyph) { %>.van-icon-<%= glyph.fileName %>:before { content: "\<%= glyph.codePoint %>"; } <% }); %> diff --git a/packages/icon/demo/index.vue b/packages/icon/demo/index.vue index fdeefbd54..40017d39e 100644 --- a/packages/icon/demo/index.vue +++ b/packages/icon/demo/index.vue @@ -10,7 +10,7 @@