build.after.js (158 lines of code) (raw):

const path = require('path'); const fs = require('fs'); const webpack = require('webpack'); // const Config = require('webpack-chain'); const { getWebpackConfig } = require('build-scripts-config'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const packageInfo = require('./package.json'); /** 自定义构建脚本 - 后置 */ module.exports = ({ context, onGetWebpackConfig, registerTask, registerCliOption }) => { const { command, commandArgs, rootDir, userConfig } = context; const { library, libraryTarget = 'umd', libraryExport } = userConfig; function setBuildConfig(config, theme = 'index') { // 调整构建目录 config.output .path(path.resolve(rootDir, 'build')) .filename('[name].js') .publicPath('./build/') // 去除默认字体资源配置 config.module.rules .delete('woff2') .delete('ttf') .delete('eot') .delete('svg'); // 自定义字体资源配置 config.module .rule('font').test(/\.(woff|woff2|eot|ttf|otf|svg)((\?|#).*)?$/) .use('file').loader('file-loader').options({ name: '[name].[ext]', publicPath: './', }); // 全局变量 config .plugin('DefinePlugin') .use(webpack.DefinePlugin, [{ __VERSION__: JSON.stringify(packageInfo.version), __THEME__: JSON.stringify(theme), }]); // 插件部分,需要 externals @alicloud/cloud-charts 本身 config.externals({ react: { root: 'React', commonjs: 'react', commonjs2: 'react', amd: 'react', }, 'react-dom': { root: 'ReactDOM', commonjs: 'react-dom', commonjs2: 'react-dom', amd: 'react-dom', }, '@alicloud/cloud-charts': { root: userConfig.library, commonjs2: '@alicloud/cloud-charts', commonjs: '@alicloud/cloud-charts', amd: '@alicloud/cloud-charts' }, }); if (commandArgs.development) { config.optimization.minimize(false); config.output .path(path.resolve(rootDir, 'buildDev')) .filename('[name].js') .publicPath('./buildDev/') } } registerCliOption({ name: 'online', commands: ['start'], }); registerCliOption({ name: 'analyzer', commands: ['build'], }); registerCliOption({ name: 'production', commands: ['build'], }); registerCliOption({ name: 'development', commands: ['build'], }); // 在线代理 if (commandArgs.online) { const onlineConfig = getWebpackConfig('development'); onlineConfig.target('web'); onlineConfig.context(rootDir); setBuildConfig(onlineConfig); onlineConfig.output .library(library) .libraryExport(libraryExport) .libraryTarget(libraryTarget); onlineConfig .entry('index') .add(path.resolve(rootDir, 'src/index.scss')) .add(path.resolve(rootDir, 'src/index.ts')); registerTask('online-web', onlineConfig); } // 插件部分 if (!commandArgs.analyzer) { const mode = command === 'start' ? 'development' : 'production'; const pluginsConfig = getWebpackConfig(mode); pluginsConfig.target('web'); pluginsConfig.context(rootDir); setBuildConfig(pluginsConfig); pluginsConfig.output .library(`${library}[name]`) .libraryExport('default') .libraryTarget(libraryTarget); const pluginPath = path.resolve(rootDir, './src/plugins'); const plugins = fs.readdirSync(pluginPath); plugins.forEach(function (plugin) { var componentStat = fs.lstatSync(pluginPath + '/' + plugin); if (!componentStat.isDirectory()) { return; } pluginsConfig .entry(plugin) .add('./src/plugins/' + plugin + '/index.tsx'); }); registerTask('plugins', pluginsConfig); } onGetWebpackConfig(config => { if (commandArgs.production) { config.module .rule('tsx') .test(/\.tsx?$/) .before('babel-loader') .use('custom-loader') .loader(path.resolve('./loader/teamix-debugger-loader.js')) .end() } }); // 调整 umd 包 webpack 配置 // config 为 webpack-chain 实例 onGetWebpackConfig('component-dist', config => { setBuildConfig(config); if (commandArgs.analyzer) { config .plugin('analyzer') .use(BundleAnalyzerPlugin); } }); // onGetWebpackConfig(config => { // console.log(Config.toString(config.toConfig())); // }); // 主题包 if (!commandArgs.online && !commandArgs.analyzer) { const themeConfig = getWebpackConfig('production'); themeConfig.target('web'); themeConfig.context(rootDir); setBuildConfig(themeConfig, 'dark'); themeConfig.module.rule('scss').use('sass-loader').tap(options => { return { ...options, // additionalData: (content, loaderContext) => { // // More information about available properties https://webpack.js.org/api/loaders/ // const { resourcePath, rootContext } = loaderContext; // const relativePath = path.relative(rootContext, resourcePath); // console.log('relativePath', relativePath); // return content; // // if (relativePath === "styles/foo.scss") { // // return "$value: 100px;" + content; // // } // // // // return "$value: 200px;" + content; // }, // 由于 build-plugin-component -> build-scripts-config -> sass-loader 版本是 8.x,所以使用 prependData。 // 如果更新了依赖版本,可以用 additionalData // prependData: (loaderContext) => { additionalData: (content, loaderContext) => { // More information about available properties https://webpack.js.org/api/loaders/ const { resourcePath, rootContext } = loaderContext; // const relativePath = path.relative(rootContext, resourcePath); const themePath = path.relative(resourcePath, path.join(rootContext, './src/themes/dark.scss')); // console.log('relativePath', relativePath, resourcePath); // if (relativePath === 'src/index.scss') { // return '@import "themes/dark";' // } return `@import "${themePath.slice(3)}"; `; }, } }) themeConfig.output .library(library) .libraryExport(libraryExport) .libraryTarget(libraryTarget); themeConfig .entry('dark') .add(path.resolve(rootDir, 'src/index.scss')) .add(path.resolve(rootDir, 'src/index.ts')); registerTask('theme-dark', themeConfig); } };