feat(cli): build package

This commit is contained in:
陈嘉涵
2019-11-20 11:19:58 +08:00
parent 6519c12656
commit 56ea702dee
10 changed files with 196 additions and 22 deletions

View File

@@ -1,9 +1,13 @@
import webpack from 'webpack';
import { start, error, success } from 'signale';
import { packageConfig } from '../config/webpack.package';
import { join } from 'path';
import { remove, copy, readdirSync } from 'fs-extra';
import { clean } from './clean';
import { remove, copy, readdirSync } from 'fs-extra';
import { compileJs } from '../compiler/compile-js';
import { compileSfc } from '../compiler/compile-sfc';
import { compileStyle } from '../compiler/compile-style';
import { genPackageEntry } from '../compiler/gen-package-entry';
import { SRC_DIR, LIB_DIR, ES_DIR } from '../common/constant';
import {
isDir,
@@ -40,15 +44,49 @@ function setModuleEnv(value: string) {
process.env.BABEL_MODULE = value;
}
function buildPackage(isMinify: boolean) {
return new Promise((resolve, reject) => {
webpack(packageConfig(isMinify), (err, stats) => {
if (err || stats.hasErrors()) {
reject();
} else {
resolve();
}
});
});
}
export async function build() {
clean();
await copy(SRC_DIR, ES_DIR);
await copy(SRC_DIR, LIB_DIR);
setModuleEnv('esmodule');
await compileDir(ES_DIR);
start('Build esmodule outputs');
try {
setModuleEnv('esmodule');
await compileDir(ES_DIR);
success('Build esmodule outputs');
} catch (err) {
error('Build esmodule outputs');
}
setModuleEnv('commonjs');
await compileDir(LIB_DIR);
start('Build commonjs outputs');
try {
setModuleEnv('commonjs');
await compileDir(LIB_DIR);
success('Build commonjs outputs');
} catch (err) {
error('Build commonjs outputs');
}
start('Build packed outputs');
try {
genPackageEntry();
await buildPackage(false);
await buildPackage(true);
success('Build packed outputs');
} catch (err) {
error('Build packed outputs');
}
}

View File

@@ -1,15 +1,15 @@
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import webpackDevConfig from '../config/webpack.site.dev';
import { getPort } from 'portfinder';
import { clean } from '../commands/clean';
import { siteDevConfig } from '../config/webpack.site.dev';
import { genMobileConfig } from '../compiler/gen-mobile-config';
import { genDesktopConfig } from '../compiler/gen-desktop-config';
function runWebpack() {
const server = new WebpackDevServer(
webpack(webpackDevConfig),
(webpackDevConfig as any).devServer
webpack(siteDevConfig),
(siteDevConfig as any).devServer
);
getPort(

View File

@@ -6,8 +6,10 @@ export const LIB_DIR = join(CWD, 'lib');
export const SRC_DIR = join(CWD, 'src');
export const DOCS_DIR = join(CWD, 'docs');
export const CONFIG_FILE = join(CWD, 'components.config.js');
export const PACKAGE_JSON_FILE = join(CWD, 'package.json');
export const DIST_DIR = join(__dirname, '../../dist');
export const CONFIG_DIR = join(__dirname, '../config');
export const PACKAGE_ENTRY_FILE = join(DIST_DIR, 'index.js');
export const MOBILE_CONFIG_FILE = join(DIST_DIR, 'mobile-config.js');
export const DESKTOP_CONFIG_FILE = join(DIST_DIR, 'desktop-config.js');
export const BABEL_CONFIG_FILE = join(CONFIG_DIR, 'babel.config.js');

View File

@@ -0,0 +1,66 @@
import { join, relative } from 'path';
import { writeFileSync } from 'fs-extra';
import { pascalize, getComponents } from '../common';
import {
SRC_DIR,
DIST_DIR,
PACKAGE_JSON_FILE,
PACKAGE_ENTRY_FILE
} from '../common/constant';
// eslint-disable-next-line
const packageJson = require(PACKAGE_JSON_FILE);
const version = process.env.PACKAGE_VERSION || packageJson.version;
function genImports(components: string[]): string {
return components
.map(name => {
const relativePath = relative(DIST_DIR, join(SRC_DIR, name));
return `import ${pascalize(name)} from '${relativePath}';`;
})
.join('\n');
}
function genExports(names: string[]): string {
return names.map(name => `${name}`).join(',\n ');
}
export function genPackageEntry() {
const components = getComponents();
const names = components.map(item => pascalize(item));
const content = `${genImports(components)}
const version = '${version}';
const components = [
${names.join(',\n ')}
];
function install() {
components.forEach(item => {
if (item.install) {
Vue.use(Component);
} else if (item.name) {
Vue.component(item.name, item);
}
});
};
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
export {
install,
version,
${genExports(names)}
};
export default {
install,
version
};
`;
writeFileSync(PACKAGE_ENTRY_FILE, content);
}

View File

@@ -1,5 +1,6 @@
import sass from 'sass';
// @ts-ignore
import FriendlyErrorsPlugin from '@nuxt/friendly-errors-webpack-plugin';
import { VueLoaderPlugin } from 'vue-loader';
import { POSTCSS_CONFIG_FILE } from '../common/constant';
@@ -16,7 +17,7 @@ const CSS_LOADERS = [
}
];
module.exports = {
export const baseConfig = {
mode: 'development',
resolve: {
extensions: ['.js', '.ts', '.tsx', '.jsx', '.vue', '.less']
@@ -72,7 +73,11 @@ module.exports = {
}
]
},
plugins: [new VueLoaderPlugin()]
plugins: [
new VueLoaderPlugin(),
new FriendlyErrorsPlugin({
clearConsole: false,
logLevel: 'WARNING'
})
]
};
export default module.exports;

View File

@@ -0,0 +1,39 @@
import { join } from 'path';
import merge from 'webpack-merge';
import { baseConfig } from './webpack.base';
import { LIB_DIR, DIST_DIR, CONFIG_FILE } from '../common/constant';
// eslint-disable-next-line
const config = require(CONFIG_FILE);
const { name } = config;
export function packageConfig(isMinify: boolean) {
return merge(baseConfig as any, {
mode: 'production',
entry: {
[name]: join(DIST_DIR, 'index.js')
},
stats: 'none',
output: {
path: LIB_DIR,
library: name,
libraryTarget: 'umd',
filename: isMinify ? '[name].min.js' : '[name].js',
umdNamedDefine: true,
// https://github.com/webpack/webpack/issues/6522
globalObject: "typeof self !== 'undefined' ? self : this"
},
externals: {
vue: {
root: 'Vue',
commonjs: 'vue',
commonjs2: 'vue',
amd: 'vue'
}
},
performance: false,
optimization: {
minimize: isMinify
}
});
}

View File

@@ -1,14 +1,14 @@
import { join } from 'path';
import merge from 'webpack-merge';
import baseConfig from './webpack.base';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { join } from 'path';
import { baseConfig } from './webpack.base';
import { CONFIG_FILE } from '../common/constant';
// eslint-disable-next-line
const config = require(CONFIG_FILE);
const title = `${config.title} - ${config.description}`;
module.exports = merge(baseConfig, {
export const siteDevConfig = merge(baseConfig as any, {
entry: {
'site-desktop': join(__dirname, '../../site/desktop/main.js'),
'site-mobile': join(__dirname, '../../site/mobile/main.js')
@@ -53,5 +53,3 @@ module.exports = merge(baseConfig, {
})
]
});
export default module.exports;

View File

@@ -1,8 +1,8 @@
import { join } from 'path';
import merge from 'webpack-merge';
import config from './webpack.site.dev';
import { siteDevConfig } from './webpack.site.dev';
module.exports = merge(config, {
export const sitePrdConfig = merge(siteDevConfig, {
mode: 'production',
output: {
path: join(__dirname, '../../site/dist'),
@@ -11,5 +11,3 @@ module.exports = merge(config, {
chunkFilename: 'async_[name].[chunkhash:8].js'
}
});
export default module.exports;