diff --git a/@types/index.d.ts b/@types/index.d.ts index 60a39da..0a2abf4 100644 --- a/@types/index.d.ts +++ b/@types/index.d.ts @@ -237,6 +237,7 @@ declare namespace build { */ namespace ConfigOptions { type webpackMode = 'development' | 'production' | 'none' + type webpackConfigMode = webpackMode | 'svg' /** * getStyle 额外参数 @@ -250,7 +251,7 @@ declare namespace build { */ interface getOptionsInject { argv: BuildService.parsedArgs - mode: ConfigOptions.webpackMode + mode: ConfigOptions.webpackConfigMode /** * 注入的上下文 @@ -358,6 +359,7 @@ declare namespace build { base?: Configuration client?: Configuration server?: serverConfig + svg?: serverConfig } /** @@ -379,6 +381,10 @@ declare namespace build { webpack: Configuration } + interface svgConfig extends Configuration { + webpack: Configuration + } + /** * server 插件 配置 */ diff --git a/bin/build-svg b/bin/build-svg new file mode 100755 index 0000000..ff2a9d0 --- /dev/null +++ b/bin/build-svg @@ -0,0 +1,7 @@ +#!/usr/bin/env node +process.env.NODE_ENV = process.env.NODE_ENV || 'development' +process.env.SPRITE = true + +const argv = require('./utils').getArgv() + +require('../dist/build-svg').start(argv) \ No newline at end of file diff --git a/doc/src/store/editor/index.ts b/doc/src/store/editor/index.ts index 643f246..cb5ca81 100644 --- a/doc/src/store/editor/index.ts +++ b/doc/src/store/editor/index.ts @@ -1,14 +1,10 @@ export * from './type' -import Vue from 'vue' -import Vuex from 'vuex' import actions, { dispatch } from './actions' import mutations, { commit, getState } from './mutations' import getters from './getters' import state from './state' -Vue.use(Vuex) - export default { namespaced: true, state: state(), diff --git a/package.json b/package.json index b70fd9d..2412f26 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ ], "bin": { "service:build": "./bin/build", + "service:build-svg": "./bin/build-svg", "service:dev": "./bin/dev", "bootstrap:storybook": "./bin/storybook" }, diff --git a/src/bin/build-svg.ts b/src/bin/build-svg.ts new file mode 100755 index 0000000..705af7d --- /dev/null +++ b/src/bin/build-svg.ts @@ -0,0 +1,23 @@ +import { BuildService } from '@types' +import consola from 'consola' +import { svgBuild } from 'src/build' +import { simpleInitConfig } from 'src/utils' + +async function buildMain(argv: BuildService.parsedArgs) { + consola.ready(`@bestminr/build-svg v${argv.version}`) + consola.start('start with SPRITE mode') + const options = await simpleInitConfig(argv, 'svg') + + svgBuild() + + // const webpack: any = options.webpack + // const svgConfig = webpack.svg + // console.log('-------------------------------------') + // console.log('svgConfig', JSON.stringify(svgConfig, null, 2)) + // console.log('-------------------------------------') + // delete options.webpack + // console.log('options', JSON.stringify(options, null, 2)) + // console.log('-------------------------------------') +} + +export { buildMain as start } \ No newline at end of file diff --git a/src/build.ts b/src/build.ts index f2fc878..15b20f5 100644 --- a/src/build.ts +++ b/src/build.ts @@ -1,5 +1,6 @@ import { getConfig } from 'src/utils' -import { compiler } from 'src-utils-compiler' +import { compiler, svgCompiler } from 'src-utils-compiler' +import consola from 'consola' export function serverBuild() { const config = getConfig() @@ -17,3 +18,15 @@ export function serverBuild() { 'production' ) } + +export function svgBuild() { + const config = getConfig() + const svgConfig: any = config.webpack ? config.webpack.svg || {} : {} + + if (svgConfig) { + svgCompiler(svgConfig) + } else { + consola.fatal('[svgBuild] svgConfig is undefined!') + return process.exit(1) + } +} \ No newline at end of file diff --git a/src/config/index.ts b/src/config/index.ts index b7ef639..ead6bb5 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,8 +1,9 @@ import { getClientConfig, getClientConfigSync } from './webpack.client.config' +import { getSvgConfig } from './webpack.svg.config' import { getServerConfig } from './webpack.server.config' import HappyPack from 'happypack' -export { getClientConfig, getServerConfig, getClientConfigSync } +export { getClientConfig, getServerConfig, getClientConfigSync, getSvgConfig } /** * 制作 HappyPack plugin diff --git a/src/config/webpack.base.config.ts b/src/config/webpack.base.config.ts index 9542b7a..574b854 100644 --- a/src/config/webpack.base.config.ts +++ b/src/config/webpack.base.config.ts @@ -12,107 +12,109 @@ import { ConfigOptions } from '@types' export function getBaseConfig(options: ConfigOptions.options) { if (!(options.babelrc && options.webpack)) { - consola.fatal( - 'getBaseConfig options.babelrc or options.webpack is undefined' - ) + consola.fatal('getBaseConfig options.babelrc or options.webpack is undefined') return process.exit(1) } + const base = options.webpack ? options.webpack.base || {} : {} + // consola.fatal(tsLoader) + + return (merge as any)(getCommonBaseConfig(options), base) +} + +export function getCommonBaseConfig(options: ConfigOptions.options) { + if (!(options.babelrc && options.webpack)) { + consola.fatal('[getCommonBaseConfig] options.babelrc or options.webpack is undefined') + return process.exit(1) + } + const mode = options.webpack.mode || 'production' const isProd = mode === 'production' - const base = options.webpack ? options.webpack.base || {} : {} + const babelLoder = { + loader: 'babel-loader', + options: options.babelrc + } const tsLoader: any = { loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/], transpileOnly: true, - happyPackMode: true, + happyPackMode: true } } if (options.tsconfig) { tsLoader.options.context = options.rootDir tsLoader.options.configFile = options.tsconfig } - // consola.fatal(tsLoader) - - const babelLoder = { - loader: 'babel-loader', - options: options.babelrc - } - - return (merge as any)( - getCommonConfig(mode), - { - mode: isProd ? 'production' : 'development', - context: options.rootDir, - devtool: isProd ? false : '#cheap-module-source-map', - output: { - path: './dist', - filename: '[chunkhash].js' - }, - resolve: { - extensions: ['.ts', '.js', '.vue', '.json'] - }, - module: { - noParse: /es6-promise\.js$/, - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - compilerOptions: { - preserveWhitespace: false - } + return (merge as any)(getCommonConfig(mode), { + mode: isProd ? 'production' : 'development', + context: options.rootDir, + devtool: isProd ? false : '#cheap-module-source-map', + output: { + path: './dist', + filename: '[chunkhash].js' + }, + resolve: { + extensions: ['.ts', '.js', '.vue', '.json'] + }, + module: { + noParse: /es6-promise\.js$/, + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + compilerOptions: { + preserveWhitespace: false } - }, - { - test: /\.js$/, - loader: 'happypack/loader?id=babel', - exclude: /node_modules/ - }, - { - test: /\.tsx?$/, - loader: 'happypack/loader?id=ts', - exclude: /node_modules/ } - ] - }, - optimization: { - minimizer: [ - new UglifyJsPlugin({ - uglifyOptions: { - compress: { - warnings: false - }, - output: { - ecma: 5 - }, - ecma: 8 + }, + { + test: /\.js$/, + loader: 'happypack/loader?id=babel', + exclude: /node_modules/ + }, + { + test: /\.tsx?$/, + loader: 'happypack/loader?id=ts', + exclude: /node_modules/ + } + ] + }, + optimization: { + minimizer: [ + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + }, + output: { + ecma: 5 }, - parallel: true + ecma: 8 + }, + parallel: true + }) + ] + }, + performance: { + maxEntrypointSize: 1024 * 300, + maxAssetSize: 1024 * 300, + hints: isProd ? 'warning' : false + }, + plugins: (isProd + ? [] + : [ + new Webpackbar(), + new FriendlyErrorsPlugin(), + new ForkTsCheckerWebpackPlugin({ + vue: true, // 开启以检测 .vue 文件中的类型错误 + ignoreDiagnostics: [2339] }) ] - }, - performance: { - maxEntrypointSize: 1024 * 300, - maxAssetSize: 1024 * 300, - hints: isProd ? 'warning' : false - }, - plugins: (isProd - ? [] - : [ - new Webpackbar(), - new FriendlyErrorsPlugin(), - new ForkTsCheckerWebpackPlugin({ - vue: true, // 开启以检测 .vue 文件中的类型错误 - ignoreDiagnostics: [2339] - }) - ] - ).concat([ - new VueLoaderPlugin(), - makeHappyPack('ts', [tsLoader]), - makeHappyPack('babel', [babelLoder]) - ]) - }, - base - ) + ).concat([ + new VueLoaderPlugin(), + makeHappyPack('ts', [tsLoader]), + makeHappyPack('babel', [babelLoder]) + ]) + }) } diff --git a/src/config/webpack.config.config.ts b/src/config/webpack.config.config.ts index 3a141e1..1c07922 100644 --- a/src/config/webpack.config.config.ts +++ b/src/config/webpack.config.config.ts @@ -19,11 +19,7 @@ export const babelLoder = { } } -export function getConfigConfig({ - rootDir -}: { - rootDir: string -}): webpack.Configuration { +export function getConfigConfig({ rootDir }: { rootDir: string }): webpack.Configuration { return (merge as any)(getCommonConfig('development'), { name: 'config', devtool: false, @@ -53,4 +49,4 @@ export function getConfigConfig({ }, plugins: [] }) -} +} \ No newline at end of file diff --git a/src/config/webpack.server.config.ts b/src/config/webpack.server.config.ts index 93392c3..e604482 100644 --- a/src/config/webpack.server.config.ts +++ b/src/config/webpack.server.config.ts @@ -57,7 +57,7 @@ export function getServerConfig(options: ConfigOptions.options) { ) } else { consola.fatal( - 'getServerConfig options.webpack.server is undefined' + '[getServerConfig] options.webpack.server is undefined' ) return process.exit(1) } diff --git a/src/config/webpack.svg.config.ts b/src/config/webpack.svg.config.ts new file mode 100644 index 0000000..26bee67 --- /dev/null +++ b/src/config/webpack.svg.config.ts @@ -0,0 +1,35 @@ +import merge from 'webpack-merge' +import { getCommonBaseConfig } from './webpack.base.config' +import consola from 'consola' + +import { ConfigOptions } from '@types' + +export function getSvgConfig(options: ConfigOptions.options) { + if (!(options.webpack && options.webpack.mode)) { + consola.fatal( + '[getSvgConfig] options.webpack or options.webpack.mode is undefined' + ) + return process.exit(1) + } + if (options.webpack.svg) { + const svg = options.webpack.svg.webpack || options.webpack.svg || {} + const mode = options.webpack.mode || 'production' + const base: any = options.webpack ? options.webpack.base || {} : {} + return (merge as any)( + getCommonBaseConfig(options), + { + name: 'svg', + mode, + devtool: false, + output: base.output, + resolve: base.resolve + }, + svg + ) + } else { + consola.fatal( + '[getServerConfig] options.webpack.svg is undefined' + ) + return process.exit(1) + } +} diff --git a/src/utils/compiler.webpack.ts b/src/utils/compiler.webpack.ts index a85617b..e541c7c 100644 --- a/src/utils/compiler.webpack.ts +++ b/src/utils/compiler.webpack.ts @@ -154,13 +154,28 @@ export function compiler( } } + +export function svgCompiler(config: ConfigOptions.options.svgConfig) { + const compiler = getCompiler(config) + compiler.run((err, stats) => { + console.log( + stats.toString({ + colors: true, + errors: false, + warnings: false + }) + ) + showError(stats, { isdev: false }) + }) +} + /** * webpack 编译 配置文件 * @param configOptions 配置文件 设置 */ export function compilerConfig( configOptions: BuildService.parsedArgs.config, - mode: ConfigOptions.webpackMode, + mode: ConfigOptions.webpackConfigMode, { rootDir }: { rootDir: string } ): Promise<() => webpack.Configuration> { return new Promise(function(this: any, done) { @@ -172,7 +187,7 @@ export function compilerConfig( consola.fatal('compilerConfig: entry or output is undefined') return process.exit(1) } - + if (mode === 'svg') mode = 'development' webpackConfig.mode = mode webpackConfig.entry = { [entryName]: entry diff --git a/src/utils/index.ts b/src/utils/index.ts index 6bfd15f..5afa446 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -2,6 +2,7 @@ import { resolve } from 'path' import { ConfigOptions, BuildService } from '@types' import { + getSvgConfig, getClientConfig, getServerConfig, getClientConfigSync @@ -191,12 +192,17 @@ function baseSetWebpack(options: ConfigOptions.options) { */ async function setWebpack( options: ConfigOptions.options, - mode: ConfigOptions.webpackMode + mode: ConfigOptions.webpackConfigMode ) { options.webpack = options.webpack || {} - options.webpack.mode = mode - options.webpack.client = await getClientConfig(options) - baseSetWebpack(options) + if (mode === 'svg') { + options.webpack.mode = 'development' + options.webpack.svg = getSvgConfig(options) + } else { + options.webpack.mode = mode + options.webpack.client = await getClientConfig(options) + baseSetWebpack(options) + } return options } @@ -317,7 +323,7 @@ export function getUserConfigSync( async function getUserConfig( configOptions: BuildService.parsedArgs.config, injectContext: any, - mode: ConfigOptions.webpackMode, + mode: ConfigOptions.webpackConfigMode, argv: BuildService.parsedArgs ) { const rootDir = getRootDir(argv) @@ -403,6 +409,30 @@ export async function initConfig( return options } +export async function simpleInitConfig( + argv: BuildService.parsedArgs, + mode: ConfigOptions.webpackConfigMode +) { + const configOptions = getConfigFileOptions(argv) + + const options: ConfigOptions.options = await getUserConfig( + configOptions, + {}, + mode, + argv + ) + + await setWebpack(options, mode) + + options.buildVersion = argv.version + + setVersion(options) + + setBuildServiceConfig(options) + + return options +} + /** * 检测 是否启用 dll 启动 * * **必须** 放置在 **setWebpack** 设置webpack **之前** diff --git a/webpack.js b/webpack.js index 76ef072..a936c60 100644 --- a/webpack.js +++ b/webpack.js @@ -10,6 +10,7 @@ module.exports = { entry: { index: resolve('./src/index.ts'), build: resolve('./src/bin/build.ts'), + 'build-svg': resolve('./src/bin/build-svg.ts'), dev: resolve('./src/bin/dev.ts'), 'bootstrap-storybook': resolve('./src/bin/bootstrap-storybook.ts'), 'empty-module': resolve('./src/utils/empty-module.js')