chore(cli): extract create-vant-cli-app package

This commit is contained in:
陈嘉涵
2020-01-16 18:02:34 +08:00
parent 62a1b39b2b
commit 5bb9a31e28
32 changed files with 2492 additions and 697 deletions

View File

@@ -1,15 +0,0 @@
import { GENERATOR_DIR, CWD } from '../common/constant';
import { VantCliGenerator } from '../compiler/vant-cli-generator';
export async function create() {
const generator = new VantCliGenerator([], {
env: {
cwd: CWD
},
resolved: GENERATOR_DIR
});
return new Promise(resolve => {
generator.run(resolve);
});
}

View File

@@ -33,13 +33,15 @@ export const CACHE_DIR = join(ROOT, 'node_modules/.cache');
// Relative paths
export const DIST_DIR = join(__dirname, '../../dist');
export const CONFIG_DIR = join(__dirname, '../config');
export const GENERATOR_DIR = join(__dirname, '../../generators');
// Dist files
export const PACKAGE_ENTRY_FILE = join(DIST_DIR, 'package-entry.js');
export const PACKAGE_STYLE_FILE = join(DIST_DIR, 'package-style.css');
export const SITE_MODILE_SHARED_FILE = join(DIST_DIR, 'site-mobile-shared.js');
export const SITE_DESKTOP_SHARED_FILE = join(DIST_DIR, 'site-desktop-shared.js');
export const SITE_DESKTOP_SHARED_FILE = join(
DIST_DIR,
'site-desktop-shared.js'
);
export const STYPE_DEPS_JSON_FILE = join(DIST_DIR, 'style-deps.json');
// Config files
@@ -63,7 +65,11 @@ export function getPackageJson() {
export function getVantConfig() {
delete require.cache[VANT_CONFIG_FILE];
return require(VANT_CONFIG_FILE);
try {
return require(VANT_CONFIG_FILE);
} catch (err) {
return {};
}
}
function getSrcDir() {

View File

@@ -1,9 +1,11 @@
import webpack from 'webpack';
import { packageConfig } from '../config/webpack.package';
import { getPackageConfig } from '../config/webpack.package';
export async function compilePackage(isMinify: boolean) {
return new Promise((resolve, reject) => {
webpack(packageConfig(isMinify), (err, stats) => {
const config = getPackageConfig(isMinify);
webpack(config, (err, stats) => {
if (err || stats.hasErrors()) {
reject();
} else {

View File

@@ -5,8 +5,8 @@ import WebpackDevServer from 'webpack-dev-server';
import { get } from 'lodash';
import { getPort } from 'portfinder';
import { GREEN } from '../common/constant';
import { siteDevConfig } from '../config/webpack.site.dev';
import { sitePrdConfig } from '../config/webpack.site.prd';
import { getSiteDevConfig } from '../config/webpack.site.dev';
import { getSitePrdConfig } from '../config/webpack.site.prd';
function logServerInfo(port: number) {
const local = `http://localhost:${port}/`;
@@ -17,16 +17,16 @@ function logServerInfo(port: number) {
console.log(` ${chalk.bold('Network')}: ${chalk.hex(GREEN)(network)}`);
}
function runDevServer(port: number) {
const server = new WebpackDevServer(
webpack(siteDevConfig),
siteDevConfig.devServer
);
function runDevServer(
port: number,
config: ReturnType<typeof getSiteDevConfig>
) {
const server = new WebpackDevServer(webpack(config), config.devServer);
// this is a hack to disable wds status log
(server as any).showStatus = function() {};
const host = get(siteDevConfig.devServer, 'host', 'localhost');
const host = get(config.devServer, 'host', 'localhost');
server.listen(port, host, (err?: Error) => {
if (err) {
console.log(err);
@@ -35,9 +35,11 @@ function runDevServer(port: number) {
}
function watch() {
const config = getSiteDevConfig();
getPort(
{
port: siteDevConfig.devServer!.port
port: config.devServer!.port
},
(err, port) => {
if (err) {
@@ -46,14 +48,16 @@ function watch() {
}
logServerInfo(port);
runDevServer(port);
runDevServer(port, config);
}
);
}
function build() {
return new Promise((resolve, reject) => {
webpack(sitePrdConfig, (err, stats) => {
const config = getSitePrdConfig();
webpack(config, (err, stats) => {
if (err || stats.hasErrors()) {
reject();
} else {

View File

@@ -5,8 +5,6 @@ import { getDeps, clearDepsCache, fillExt } from './get-deps';
import { getComponents, smartOutputFile } from '../common';
import { SRC_DIR, STYPE_DEPS_JSON_FILE } from '../common/constant';
const components = getComponents();
function matchPath(path: string, component: string): boolean {
return path
.replace(SRC_DIR, '')
@@ -23,7 +21,7 @@ export function checkStyleExists(component: string) {
}
// analyze component dependencies
function analyzeComponentDeps(component: string) {
function analyzeComponentDeps(components: string[], component: string) {
const checkList: string[] = [];
const componentEntry = fillExt(join(SRC_DIR, component, 'index'));
const record = new Set();
@@ -54,7 +52,7 @@ function analyzeComponentDeps(component: string) {
type DepsMap = Record<string, string[]>;
function getSequence(depsMap: DepsMap) {
function getSequence(components: string[], depsMap: DepsMap) {
const sequence: string[] = [];
const record = new Set();
@@ -94,16 +92,18 @@ function getSequence(depsMap: DepsMap) {
}
export async function genStyleDepsMap() {
const components = getComponents();
return new Promise(resolve => {
clearDepsCache();
const map = {} as DepsMap;
components.forEach(component => {
map[component] = analyzeComponentDeps(component);
map[component] = analyzeComponentDeps(components, component);
});
const sequence = getSequence(map);
const sequence = getSequence(components, map);
Object.keys(map).forEach(key => {
map[key] = map[key].sort(

View File

@@ -1,72 +0,0 @@
import chalk from 'chalk';
import { join } from 'path';
import { consola, slimPath } from '../common/logger';
import { CWD, GENERATOR_DIR } from '../common/constant';
import Generator from 'yeoman-generator';
const TEMPLATES = join(GENERATOR_DIR, 'templates');
const PROMPTS = [
{
type: 'input',
name: 'name',
message: 'Your package name'
}
];
export class VantCliGenerator extends Generator {
inputs = {
name: ''
};
async prompting() {
return this.prompt(PROMPTS).then(inputs => {
this.inputs = inputs as any;
});
}
writing() {
consola.info(`Creating project in ${slimPath(CWD)}\n`);
const copy = (from: string, to?: string) => {
this.fs.copy(join(TEMPLATES, from), this.destinationPath(to || from));
};
const copyTpl = (name: string) => {
this.fs.copyTpl(
join(TEMPLATES, name),
this.destinationPath(name),
this.inputs
);
};
copy('.gitignore');
copy('.eslintignore');
copy('babel.config.js');
copy('src/**/*', 'src');
copy('docs/**/*', 'docs');
copyTpl('package.json');
copyTpl('vant.config.js');
}
install() {
console.log();
consola.info('Install dependencies...\n');
this.installDependencies({
npm: false,
bower: false,
yarn: true,
skipMessage: true
});
}
end() {
console.log();
consola.success(
`Successfully created project ${chalk.yellow(this.inputs.name)}.`
);
consola.success(
`Now you can run ${chalk.yellow('yarn dev')} to start development!`
);
}
}

View File

@@ -4,7 +4,7 @@ import { baseConfig } from './webpack.base';
import { getVantConfig, getWebpackConfig, setBuildTarget } from '../common';
import { LIB_DIR, ES_DIR } from '../common/constant';
export function packageConfig(isMinify: boolean) {
export function getPackageConfig(isMinify: boolean) {
const { name } = getVantConfig();
setBuildTarget('package');

View File

@@ -13,91 +13,95 @@ import {
SITE_DESKTOP_SHARED_FILE
} from '../common/constant';
const vantConfig = getVantConfig();
const baiduAnalytics = get(vantConfig, 'site.baiduAnalytics');
export function getSiteDevBaseConfig() {
const vantConfig = getVantConfig();
const baiduAnalytics = get(vantConfig, 'site.baiduAnalytics');
function getSiteConfig() {
const siteConfig = vantConfig.site;
function getSiteConfig() {
const siteConfig = vantConfig.site;
if (siteConfig.locales) {
return siteConfig.locales[siteConfig.defaultLang || 'en-US'];
}
return siteConfig;
}
function getTitle(config: { title: string, description?: string }) {
let { title } = config;
if (config.description) {
title += ` - ${config.description}`;
}
return title;
}
const siteConfig = getSiteConfig();
const title = getTitle(siteConfig);
export const siteDevBaseConfig = merge(baseConfig as any, {
entry: {
'site-desktop': [join(__dirname, '../../site/desktop/main.js')],
'site-mobile': [join(__dirname, '../../site/mobile/main.js')]
},
devServer: {
port: 8080,
quiet: true,
host: '0.0.0.0',
stats: 'errors-only',
publicPath: '/',
disableHostCheck: true
},
resolve: {
alias: {
'site-mobile-shared': SITE_MODILE_SHARED_FILE,
'site-desktop-shared': SITE_DESKTOP_SHARED_FILE
if (siteConfig.locales) {
return siteConfig.locales[siteConfig.defaultLang || 'en-US'];
}
},
output: {
chunkFilename: '[name].js'
},
optimization: {
splitChunks: {
cacheGroups: {
chunks: {
chunks: 'all',
minChunks: 2,
minSize: 0,
name: 'chunks'
return siteConfig;
}
function getTitle(config: { title: string; description?: string }) {
let { title } = config;
if (config.description) {
title += ` - ${config.description}`;
}
return title;
}
const siteConfig = getSiteConfig();
const title = getTitle(siteConfig);
return merge(baseConfig as any, {
entry: {
'site-desktop': [join(__dirname, '../../site/desktop/main.js')],
'site-mobile': [join(__dirname, '../../site/mobile/main.js')]
},
devServer: {
port: 8080,
quiet: true,
host: '0.0.0.0',
stats: 'errors-only',
publicPath: '/',
disableHostCheck: true
},
resolve: {
alias: {
'site-mobile-shared': SITE_MODILE_SHARED_FILE,
'site-desktop-shared': SITE_DESKTOP_SHARED_FILE
}
},
output: {
chunkFilename: '[name].js'
},
optimization: {
splitChunks: {
cacheGroups: {
chunks: {
chunks: 'all',
minChunks: 2,
minSize: 0,
name: 'chunks'
}
}
}
}
},
plugins: [
new WebpackBar({
name: 'Vant Cli',
color: GREEN
}),
new VantCliSitePlugin(),
new HtmlWebpackPlugin({
title,
logo: siteConfig.logo,
description: siteConfig.description,
chunks: ['chunks', 'site-desktop'],
template: join(__dirname, '../../site/desktop/index.html'),
filename: 'index.html',
baiduAnalytics
}),
new HtmlWebpackPlugin({
title,
logo: siteConfig.logo,
description: siteConfig.description,
chunks: ['chunks', 'site-mobile'],
template: join(__dirname, '../../site/mobile/index.html'),
filename: 'mobile.html',
baiduAnalytics
})
]
});
},
plugins: [
new WebpackBar({
name: 'Vant Cli',
color: GREEN
}),
new VantCliSitePlugin(),
new HtmlWebpackPlugin({
title,
logo: siteConfig.logo,
description: siteConfig.description,
chunks: ['chunks', 'site-desktop'],
template: join(__dirname, '../../site/desktop/index.html'),
filename: 'index.html',
baiduAnalytics
}),
new HtmlWebpackPlugin({
title,
logo: siteConfig.logo,
description: siteConfig.description,
chunks: ['chunks', 'site-mobile'],
template: join(__dirname, '../../site/mobile/index.html'),
filename: 'mobile.html',
baiduAnalytics
})
]
});
}
export const siteDevConfig = merge(siteDevBaseConfig, getWebpackConfig());
export function getSiteDevConfig() {
return merge(getSiteDevBaseConfig(), getWebpackConfig());
}

View File

@@ -1,24 +1,26 @@
import merge from 'webpack-merge';
import { get } from 'lodash';
import { getVantConfig, getWebpackConfig } from '../common';
import { siteDevBaseConfig } from './webpack.site.dev';
import { getSiteDevBaseConfig } from './webpack.site.dev';
import { SITE_DIST_DIR } from '../common/constant';
const vantConfig = getVantConfig();
const outputDir = get(vantConfig, 'build.site.outputDir', SITE_DIST_DIR);
const publicPath = get(vantConfig, 'build.site.publicPath', '/');
export const sitePrdConfig = merge(
siteDevBaseConfig,
{
mode: 'production',
stats: 'none',
output: {
publicPath,
path: outputDir,
filename: '[name].[hash:8].js',
chunkFilename: 'async_[name].[chunkhash:8].js'
}
},
getWebpackConfig()
);
export function getSitePrdConfig() {
return merge(
getSiteDevBaseConfig(),
{
mode: 'production',
stats: 'none',
output: {
publicPath,
path: outputDir,
filename: '[name].[hash:8].js',
chunkFilename: 'async_[name].[chunkhash:8].js'
}
},
getWebpackConfig()
);
}

View File

@@ -6,7 +6,6 @@ import { lint } from './commands/lint';
import { test } from './commands/jest';
import { clean } from './commands/clean';
import { build } from './commands/build';
import { create } from './commands/create';
import { release } from './commands/release';
import { changelog } from './commands/changelog';
import { buildSite } from './commands/build-site';
@@ -41,10 +40,6 @@ command('build')
.option('--watch', 'Watch file change')
.action(build);
command('create')
.description('Create a new project')
.action(create);
command('release')
.description('Compile components and release it')
.action(release);