Compare commits

..

No commits in common. "d8afff078ade5799b3f28247c9f36a11a614f217" and "92f6a6a66243b5a9743f0223918d92491a36e825" have entirely different histories.

18 changed files with 138 additions and 282 deletions

View File

@ -60,7 +60,7 @@
"vue": "^3.0.0" "vue": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {
"@vant/cli": "^3.10.0", "@vant/cli": "^3.9.2",
"@vant/area-data": "^1.0.0", "@vant/area-data": "^1.0.0",
"@vue/compiler-sfc": "^3.0.6", "@vue/compiler-sfc": "^3.0.6",
"prettier": "2.1.0", "prettier": "2.1.0",

View File

@ -1,18 +1,5 @@
# 更新日志 # 更新日志
## v3.10.0
`2021-04-10`
- 新增 `site.simulator` 选项
- 支持 iframe 通信跨域
## v3.9.3
`2021-04-10`
- 新增 `build.namedExport` 选项
## v3.9.2 ## v3.9.2
`2021-04-04` `2021-04-04`

View File

@ -5,8 +5,6 @@
- [name](#name) - [name](#name)
- [build.css](#buildcss) - [build.css](#buildcss)
- [build.site](#buildsite) - [build.site](#buildsite)
- [build.srcDir](#buildsrcdir)
- [build.namedExport](#buildnamedexport)
- [site.title](#sitetitle) - [site.title](#sitetitle)
- [site.logo](#sitelogo) - [site.logo](#sitelogo)
- [site.description](#sitedescription) - [site.description](#sitedescription)
@ -15,7 +13,6 @@
- [site.baiduAnalytics](#sitebaiduanalytics) - [site.baiduAnalytics](#sitebaiduanalytics)
- [site.searchConfig](#sitesearchconfig) - [site.searchConfig](#sitesearchconfig)
- [site.hideSimulator](#sitehidesimulator) - [site.hideSimulator](#sitehidesimulator)
- [site.simulator.url](#sitesimulatorurl)
- [Webpack](#webpack) - [Webpack](#webpack)
- [Babel](#babel) - [Babel](#babel)
- [默认配置](#-1) - [默认配置](#-1)
@ -127,17 +124,6 @@ module.exports = {
}; };
``` ```
### build.namedExport
- Type: `boolean`
- Default: `false`
是否通过 Named Export 对组件进行导出。
未开启此选项时,会通过 `export default from 'xxx'` 导出组件内部的默认模块。
开启此选项后,会通过 `export * from 'xxx'` 导出组件内部的所有模块、类型定义。
### site.title ### site.title
- Type: `string` - Type: `string`
@ -246,13 +232,6 @@ module.exports = {
是否隐藏所有页面右侧的手机模拟器,默认不隐藏 是否隐藏所有页面右侧的手机模拟器,默认不隐藏
### site.simulator.url
- Type: `string`
- Default: -
自定义手机模拟器的 iframe URL 地址。
### site.htmlPluginOptions ### site.htmlPluginOptions
- Type: `object` - Type: `object`

View File

@ -1,10 +1,10 @@
{ {
"name": "@vant/cli", "name": "@vant/cli",
"version": "3.10.0", "version": "3.9.2",
"main": "lib/index.js", "main": "lib/index.js",
"typings": "lib/index.d.ts", "typings": "lib/index.d.ts",
"bin": { "bin": {
"vant-cli": "./lib/bin.js" "vant-cli": "./lib/index.js"
}, },
"engines": { "engines": {
"node": ">=10" "node": ">=10"

View File

@ -2,76 +2,28 @@
* 同步父窗口和 iframe vue-router 状态 * 同步父窗口和 iframe vue-router 状态
*/ */
import { config } from 'site-desktop-shared'; import { iframeReady, isMobile } from '.';
let queue = []; window.syncPath = function() {
let isIframeReady = false;
function iframeReady(callback) {
if (isIframeReady) {
callback();
} else {
queue.push(callback);
}
}
if (window.top === window) {
window.addEventListener('message', (event) => {
if (event.data.type === 'iframeReady') {
isIframeReady = true;
queue.forEach((callback) => callback());
queue = [];
}
});
} else {
window.top.postMessage({ type: 'iframeReady' }, '*');
}
function getCurrentDir() {
const router = window.vueRouter; const router = window.vueRouter;
const { path } = router.currentRoute.value; const isInIframe = window !== window.top;
const currentDir = router.currentRoute.value.path;
if (config.site.simulator?.routeMapper) { if (isInIframe) {
return config.site.simulator?.routeMapper(path); window.top.replacePath(currentDir);
} } else if (!isMobile) {
return path;
}
export function syncPathToParent() {
window.top.postMessage(
{
type: 'replacePath',
value: getCurrentDir(),
},
'*'
);
}
export function syncPathToChild() {
const iframe = document.querySelector('iframe'); const iframe = document.querySelector('iframe');
if (iframe) { if (iframe) {
iframeReady(() => { iframeReady(iframe, () => {
iframe.contentWindow.postMessage( iframe.contentWindow.replacePath(currentDir);
{
type: 'replacePath',
value: getCurrentDir(),
},
'*'
);
}); });
} }
}
export function listenToSyncPath(router) {
window.addEventListener('message', (event) => {
if (event.data?.type !== 'replacePath') {
return;
} }
};
const path = event.data?.value || ''; window.replacePath = function(path = '') {
// should preserve hash for anchor // should preserve hash for anchor
if (router.currentRoute.value.path !== path) { if (window.vueRouter.currentRoute.value.path !== path) {
router.replace(path).catch(() => {}); window.vueRouter.replace(path).catch(() => {});
} }
}); };
}

View File

@ -1,3 +1,20 @@
function iframeReady(iframe, callback) {
const doc = iframe.contentDocument || iframe.contentWindow.document;
const interval = () => {
if (iframe.contentWindow.replacePath) {
callback();
} else {
setTimeout(interval, 50);
}
};
if (doc.readyState === 'complete') {
interval();
} else {
iframe.onload = interval;
}
}
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
const isMobile = /ios|iphone|ipod|ipad|android/.test(ua); const isMobile = /ios|iphone|ipod|ipad|android/.test(ua);
@ -8,4 +25,4 @@ export function decamelize(str, sep = '-') {
.toLowerCase(); .toLowerCase();
} }
export { isMobile }; export { isMobile, iframeReady };

View File

@ -25,20 +25,15 @@ export default {
}, },
data() { data() {
const path = location.pathname.replace(/\/index(\.html)?/, '/');
return { return {
simulator: `${path}mobile.html${location.hash}`,
hasSimulator: true, hasSimulator: true,
}; };
}, },
computed: { computed: {
simulator() {
if (config.site.simulator?.url) {
return config.site.simulator?.url;
}
const path = location.pathname.replace(/\/index(\.html)?/, '/');
return `${path}mobile.html${location.hash}`;
},
lang() { lang() {
const { lang } = this.$route.meta; const { lang } = this.$route.meta;
return lang || ''; return lang || '';

View File

@ -214,7 +214,7 @@ export default {
position: absolute; position: absolute;
top: 34px; top: 34px;
left: 0; left: 0;
width: 100%; width: 100px;
z-index: 99; z-index: 99;
color: #333; color: #333;
line-height: 36px; line-height: 36px;

View File

@ -3,7 +3,7 @@ import { createRouter, createWebHashHistory } from 'vue-router';
import { isMobile, decamelize } from '../common'; import { isMobile, decamelize } from '../common';
import { config, documents } from 'site-desktop-shared'; import { config, documents } from 'site-desktop-shared';
import { getLang, setDefaultLang } from '../common/locales'; import { getLang, setDefaultLang } from '../common/locales';
import { listenToSyncPath, syncPathToChild } from '../common/iframe-router'; import '../common/iframe-router';
if (isMobile) { if (isMobile) {
location.replace('mobile.html' + location.hash); location.replace('mobile.html' + location.hash);
@ -117,11 +117,7 @@ export const router = createRouter({
}); });
router.afterEach(() => { router.afterEach(() => {
nextTick(syncPathToChild); nextTick(() => window.syncPath());
}); });
if (config.site.simulator?.syncPathFromSimulator !== false) {
listenToSyncPath(router);
}
window.vueRouter = router; window.vueRouter = router;

View File

@ -4,7 +4,7 @@ import DemoHome from './components/DemoHome';
import { decamelize } from '../common'; import { decamelize } from '../common';
import { demos, config } from 'site-mobile-shared'; import { demos, config } from 'site-mobile-shared';
import { getLang, setDefaultLang } from '../common/locales'; import { getLang, setDefaultLang } from '../common/locales';
import { listenToSyncPath, syncPathToParent } from '../common/iframe-router'; import '../common/iframe-router';
const { locales, defaultLang } = config.site; const { locales, defaultLang } = config.site;
@ -97,10 +97,8 @@ export const router = createRouter({
watch(router.currentRoute, () => { watch(router.currentRoute, () => {
if (!router.currentRoute.value.redirectedFrom) { if (!router.currentRoute.value.redirectedFrom) {
nextTick(syncPathToParent); nextTick(window.syncPath);
} }
}); });
listenToSyncPath(router);
window.vueRouter = router; window.vueRouter = router;

View File

@ -1,57 +0,0 @@
#!/usr/bin/env node
import { command, parse, version } from 'commander';
import {
dev,
lint,
test,
clean,
build,
release,
changelog,
buildSite,
commitLint,
cliVersion,
} from '.';
version(`@vant/cli ${cliVersion}`);
command('dev').description('Run webpack dev server').action(dev);
command('lint').description('Run eslint and stylelint').action(lint);
command('test')
.description('Run unit tests through jest')
.option(
'--watch',
'Watch files for changes and rerun tests related to changed files'
)
.option(
'--clearCache',
'Clears the configured Jest cache directory and then exits'
)
.action(test);
command('clean').description('Clean all dist files').action(clean);
command('build')
.description('Compile components in production mode')
.option('--watch', 'Watch file change')
.action(build);
command('release')
.description('Compile components and release it')
.option('--tag <tag>', 'Release tag')
.action(release);
command('build-site')
.description('Compile site in production mode')
.action(buildSite);
command('changelog').description('Generate changelog').action(changelog);
command('commit-lint <gitParams>')
.description('Lint commit message')
.action(commitLint);
parse();

View File

@ -8,77 +8,36 @@ import {
} from '../common'; } from '../common';
import { SRC_DIR, getPackageJson, getVantConfig } from '../common/constant'; import { SRC_DIR, getPackageJson, getVantConfig } from '../common/constant';
type PathResolver = (path: string) => string; type Options = {
outputPath: string;
pathResolver?: Function;
};
function getPathByName(name: string, pathResolver?: PathResolver) { function genImports(components: string[], options: Options): string {
let path = join(SRC_DIR, name); return components
if (pathResolver) {
path = pathResolver(path);
}
return normalizePath(path);
}
function genImports(
names: string[],
pathResolver?: PathResolver,
namedExport?: boolean
): string {
return names
.map((name) => { .map((name) => {
const pascalName = pascalize(name); let path = join(SRC_DIR, name);
const importName = namedExport ? `{ ${pascalName} }` : pascalName; if (options.pathResolver) {
const importPath = getPathByName(name, pathResolver); path = options.pathResolver(path);
}
return `import ${importName} from '${importPath}';`; return `import ${pascalize(name)} from '${normalizePath(path)}';`;
}) })
.join('\n'); .join('\n');
} }
function genExports( function genExports(names: string[]): string {
names: string[], return names.map((name) => `${name}`).join(',\n ');
pathResolver?: PathResolver,
namedExport?: boolean
): string {
if (namedExport) {
const exports = names
.map((name) => `export * from '${getPathByName(name, pathResolver)}';`)
.join('\n');
return `
export {
install,
version,
};
${exports}
`;
}
return `
export {
install,
version,
${names.map(pascalize).join(',\n ')}
};
`;
} }
export function genPackageEntry({ export function genPackageEntry(options: Options) {
outputPath,
pathResolver,
}: {
outputPath: string;
pathResolver?: PathResolver;
}) {
const names = getComponents(); const names = getComponents();
const vantConfig = getVantConfig(); const vantConfig = getVantConfig();
const namedExport = get(vantConfig, 'build.namedExport', false);
const skipInstall = get(vantConfig, 'build.skipInstall', []).map(pascalize); const skipInstall = get(vantConfig, 'build.skipInstall', []).map(pascalize);
const version = process.env.PACKAGE_VERSION || getPackageJson().version; const version = process.env.PACKAGE_VERSION || getPackageJson().version;
const components = names.map(pascalize); const components = names.map(pascalize);
const content = `${genImports(names, pathResolver, namedExport)} const content = `${genImports(names, options)}
const version = '${version}'; const version = '${version}';
@ -96,7 +55,11 @@ function install(app) {
}); });
} }
${genExports(names, pathResolver, namedExport)} export {
install,
version,
${genExports(components)}
};
export default { export default {
install, install,
@ -104,5 +67,5 @@ export default {
}; };
`; `;
smartOutputFile(outputPath, content); smartOutputFile(options.outputPath, content);
} }

View File

@ -17,25 +17,25 @@ module.exports = function (api?: ConfigAPI, options: PresetOption = {}) {
return { return {
presets: [ presets: [
[ [
require.resolve('@babel/preset-env'), '@babel/preset-env',
{ {
modules: useESModules ? false : 'commonjs', modules: useESModules ? false : 'commonjs',
loose: options.loose, loose: options.loose,
}, },
], ],
require.resolve('@babel/preset-typescript'), '@babel/preset-typescript',
require('../compiler/babel-preset-vue-ts'), require('../compiler/babel-preset-vue-ts'),
], ],
plugins: [ plugins: [
[ [
require.resolve('@babel/plugin-transform-runtime'), '@babel/plugin-transform-runtime',
{ {
corejs: false, corejs: false,
useESModules, useESModules,
}, },
], ],
[ [
require.resolve('babel-plugin-import'), 'import',
{ {
libraryName: 'vant', libraryName: 'vant',
libraryDirectory: useESModules ? 'es' : 'lib', libraryDirectory: useESModules ? 'es' : 'lib',
@ -44,7 +44,7 @@ module.exports = function (api?: ConfigAPI, options: PresetOption = {}) {
'vant', 'vant',
], ],
[ [
require.resolve('@vue/babel-plugin-jsx'), '@vue/babel-plugin-jsx',
{ {
enableObjectSlots: options.enableObjectSlots, enableObjectSlots: options.enableObjectSlots,
}, },

View File

@ -14,10 +14,10 @@ import {
} from '../common/constant'; } from '../common/constant';
const CSS_LOADERS = [ const CSS_LOADERS = [
require.resolve('style-loader'), 'style-loader',
require.resolve('css-loader'), 'css-loader',
{ {
loader: require.resolve('postcss-loader'), loader: 'postcss-loader',
options: { options: {
postcssOptions: require(POSTCSS_CONFIG_FILE), postcssOptions: require(POSTCSS_CONFIG_FILE),
}, },
@ -25,7 +25,7 @@ const CSS_LOADERS = [
]; ];
const VUE_LOADER = { const VUE_LOADER = {
loader: require.resolve('vue-loader'), loader: 'vue-loader',
options: { options: {
compilerOptions: { compilerOptions: {
preserveWhitespace: false, preserveWhitespace: false,
@ -88,7 +88,7 @@ export const baseConfig: WebpackConfig = {
{ {
test: /\.(js|ts|jsx|tsx)$/, test: /\.(js|ts|jsx|tsx)$/,
exclude: /node_modules\/(?!(@vant\/cli))/, exclude: /node_modules\/(?!(@vant\/cli))/,
use: [require.resolve('babel-loader')], use: ['babel-loader'],
}, },
{ {
test: /\.css$/, test: /\.css$/,
@ -98,7 +98,7 @@ export const baseConfig: WebpackConfig = {
{ {
test: /\.less$/, test: /\.less$/,
sideEffects: true, sideEffects: true,
use: [...CSS_LOADERS, require.resolve('less-loader')], use: [...CSS_LOADERS, 'less-loader'],
}, },
{ {
test: /\.scss$/, test: /\.scss$/,
@ -106,7 +106,7 @@ export const baseConfig: WebpackConfig = {
use: [ use: [
...CSS_LOADERS, ...CSS_LOADERS,
{ {
loader: require.resolve('sass-loader'), loader: 'sass-loader',
options: { options: {
implementation: sass, implementation: sass,
}, },
@ -115,7 +115,7 @@ export const baseConfig: WebpackConfig = {
}, },
{ {
test: /\.md$/, test: /\.md$/,
use: [VUE_LOADER, require.resolve('@vant/markdown-loader')], use: [VUE_LOADER, '@vant/markdown-loader'],
}, },
], ],
}, },

View File

@ -1,5 +1,10 @@
#!/usr/bin/env node
import { command, parse, version } from 'commander';
// @ts-ignore // @ts-ignore
import packageJson from '../package.json'; import packageJson from '../package.json';
// commands
import { dev } from './commands/dev'; import { dev } from './commands/dev';
import { lint } from './commands/lint'; import { lint } from './commands/lint';
import { test } from './commands/jest'; import { test } from './commands/jest';
@ -10,18 +15,46 @@ import { changelog } from './commands/changelog';
import { buildSite } from './commands/build-site'; import { buildSite } from './commands/build-site';
import { commitLint } from './commands/commit-lint'; import { commitLint } from './commands/commit-lint';
export const cliVersion: string = packageJson.version; version(`@vant/cli ${packageJson.version}`);
process.env.VANT_CLI_VERSION = cliVersion; process.env.VANT_CLI_VERSION = packageJson.version;
export { command('dev').description('Run webpack dev server').action(dev);
dev,
lint, command('lint').description('Run eslint and stylelint').action(lint);
test,
clean, command('test')
build, .description('Run unit tests through jest')
release, .option(
changelog, '--watch',
buildSite, 'Watch files for changes and rerun tests related to changed files'
commitLint, )
}; .option(
'--clearCache',
'Clears the configured Jest cache directory and then exits'
)
.action(test);
command('clean').description('Clean all dist files').action(clean);
command('build')
.description('Compile components in production mode')
.option('--watch', 'Watch file change')
.action(build);
command('release')
.description('Compile components and release it')
.option('--tag <tag>', 'Release tag')
.action(release);
command('build-site')
.description('Compile site in production mode')
.action(buildSite);
command('changelog').description('Generate changelog').action(changelog);
command('commit-lint <gitParams>')
.description('Lint commit message')
.action(commitLint);
parse();

View File

@ -10,7 +10,7 @@ const messages = reactive<Messages>({
'zh-CN': defaultMessages, 'zh-CN': defaultMessages,
}); });
const Locale = { export default {
messages(): Message { messages(): Message {
return messages[lang.value]; return messages[lang.value];
}, },
@ -24,6 +24,3 @@ const Locale = {
deepAssign(messages, newMessages); deepAssign(messages, newMessages);
}, },
}; };
export default Locale;
export { Locale };

View File

@ -2,7 +2,6 @@ module.exports = {
name: 'vant', name: 'vant',
build: { build: {
srcDir: 'src', srcDir: 'src',
namedExport: true,
skipInstall: ['lazyload'], skipInstall: ['lazyload'],
site: { site: {
publicPath: publicPath:
@ -16,8 +15,9 @@ module.exports = {
site: { site: {
defaultLang: 'en-US', defaultLang: 'en-US',
versions: [ versions: [
{ label: 'v1', link: '/vant/v1/' }, { label: 'Vant v1', link: '/vant/v1/' },
{ label: 'v2', link: '/vant/' }, { label: 'Vant v2', link: '/vant/' },
{ label: 'Vant Weapp', link: '/vant-weapp/' },
], ],
baiduAnalytics: { baiduAnalytics: {
seed: 'ad6b5732c36321f2dafed737ac2da92f', seed: 'ad6b5732c36321f2dafed737ac2da92f',
@ -30,14 +30,10 @@ module.exports = {
locales: { locales: {
'zh-CN': { 'zh-CN': {
title: 'Vant', title: 'Vant',
description: '轻量、可靠的移动端组件库', description: '轻量、可靠的移动端 Vue 组件库',
logo: 'https://img.yzcdn.cn/vant/logo.png', logo: 'https://img.yzcdn.cn/vant/logo.png',
langLabel: '中', langLabel: '中',
links: [ links: [
{
logo: 'https://b.yzcdn.cn/vant/logo/weapp.svg',
url: 'https://vant-contrib.gitee.io/vant-weapp/',
},
{ {
logo: 'https://b.yzcdn.cn/vant/logo/github.svg', logo: 'https://b.yzcdn.cn/vant/logo/github.svg',
url: 'https://github.com/youzan/vant', url: 'https://github.com/youzan/vant',

View File

@ -1860,10 +1860,10 @@
resolved "https://registry.npm.taobao.org/@vant/area-data/download/@vant/area-data-1.0.0.tgz#063af9ccb5ccafa333d7dc28103937501cfec671" resolved "https://registry.npm.taobao.org/@vant/area-data/download/@vant/area-data-1.0.0.tgz#063af9ccb5ccafa333d7dc28103937501cfec671"
integrity sha1-Bjr5zLXMr6Mz19woEDk3UBz+xnE= integrity sha1-Bjr5zLXMr6Mz19woEDk3UBz+xnE=
"@vant/cli@^3.10.0": "@vant/cli@^3.9.2":
version "3.10.0" version "3.9.2"
resolved "https://registry.npmjs.org/@vant/cli/-/cli-3.10.0.tgz#a129adb56f15a3c31a7a2701e288ed9a642e734d" resolved "https://registry.npm.taobao.org/@vant/cli/download/@vant/cli-3.9.2.tgz#6eb7149004c8b36bc5fc08c16cc36c78bcdd3b4b"
integrity sha512-+Nj6YHxYgsgmDFrS31PiT2UwB70KO5EH3QLbzYDihoj0QfYEQmHdk+DAOeZ6IXgZR5Nb3EbZFFLKmebngYaisg== integrity sha1-brcUkATIs2vF/AjBbMNseLzdO0s=
dependencies: dependencies:
"@babel/core" "^7.12.10" "@babel/core" "^7.12.10"
"@babel/plugin-transform-runtime" "^7.12.10" "@babel/plugin-transform-runtime" "^7.12.10"