ui-default: init

将ui-default合并至主存储库便于维护
This commit is contained in:
undefined committed 2021-04-03 01:44:22 +08:00
1 parent 6317c9057f
commit 5faa54c7ca
564 files changed
+23083 -14

No files matched your search

+82
View File
@@ -0,0 +1,82 @@
/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
/* eslint-disable import/no-extraneous-dependencies */
import _ from 'lodash';
import moment from 'moment';
import gulp from 'gulp';
import log from 'fancy-log';
import chalk from 'chalk';
import svgmin from 'gulp-svgmin';
import vinylBuffer from 'vinyl-buffer';
import iconfont from 'gulp-iconfont';
import plumber from 'gulp-plumber';
import gulpif from 'gulp-if';
import nunjucks from '../plugins/gulpNunjucks';
import vjTouch from '../plugins/gulpTouch';
let isInWatchMode = false;
export const tasks = {};
const iconTimestamp = moment.utc([2020, 0, 1, 0, 0, 0, 0]).unix();
function handleWatchChange(name, r = 300) {
return _.debounce((ev) => {
log('File %s: %s', chalk.yellow(ev.type), ev.path);
tasks[name]();
}, r);
}
function offsetMtimeAtFirstBuild() {
// Offset the mtime at first build to
// workaround webpack/watchpack issue #25.
return gulpif(!isInWatchMode, vjTouch(~~((Date.now() - 30 * 1000) / 1000)));
}
export default function ({ errorHandler }) {
let iconfontTemplateArgs = null;
tasks['iconfont:template'] = () => gulp
.src('misc/icons/template/*.styl')
.pipe(nunjucks(iconfontTemplateArgs))
.pipe(gulp.dest('misc/.iconfont'))
.pipe(offsetMtimeAtFirstBuild());
tasks.iconfont = () => gulp
.src('misc/icons/*.svg')
.pipe(plumber({ errorHandler }))
.pipe(svgmin())
.pipe(gulp.dest('misc/icons'))
.pipe(offsetMtimeAtFirstBuild())
.pipe(iconfont({
fontHeight: 1000,
prependUnicode: false,
descent: 6.25 / 100 * 1000,
fontName: 'vj4icon',
formats: ['svg', 'ttf', 'eot', 'woff', 'woff2'],
timestamp: iconTimestamp,
}))
.on('glyphs', (glyphs, options) => {
iconfontTemplateArgs = { glyphs, options };
tasks['iconfont:template']();
})
.pipe(gulp.dest('misc/.iconfont'))
.pipe(vinylBuffer())
.pipe(offsetMtimeAtFirstBuild());
tasks.watch = () => {
isInWatchMode = true;
gulp.watch('misc/icons/*.svg', handleWatchChange('iconfont'));
};
for (const key in tasks) {
// gulp4 uses function name directly as task name
Object.defineProperty(tasks[key], 'name', {
value: key,
configurable: true,
});
tasks[key] = gulp.series(tasks[key]);
}
tasks.default = gulp.series(gulp.parallel(tasks.iconfont));
return tasks;
}
+177
View File
@@ -0,0 +1,177 @@
/* eslint-disable import/no-extraneous-dependencies */
import { dirname } from 'path';
import webpack from 'webpack';
import ExtractCssPlugin from 'mini-css-extract-plugin';
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
import FriendlyErrorsPlugin from 'friendly-errors-webpack-plugin';
import OptimizeCssAssetsPlugin from 'optimize-css-assets-webpack-plugin';
import CopyWebpackPlugin from 'copy-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import SpeedMeasurePlugin from 'speed-measure-webpack-plugin';
import mapWebpackUrlPrefix from '../utils/mapWebpackUrlPrefix';
import StaticManifestPlugin from '../plugins/manifest.webpack';
import root from '../utils/root';
const beautifyOutputUrl = mapWebpackUrlPrefix([
{ prefix: 'node_modules/katex/dist/', replace: './katex/' },
{ prefix: 'misc/.iconfont', replace: './ui/iconfont' },
]);
const smp = new SpeedMeasurePlugin();
export default function (env = {}) {
function babelLoader() {
return {
loader: 'babel-loader',
options: {
...require(root('babel.config.js')), // eslint-disable-line
cacheDirectory: true,
},
};
}
function cssLoader() {
return {
loader: 'css-loader',
options: { importLoaders: 1 },
};
}
function postcssLoader() {
return {
loader: 'postcss-loader',
options: { sourceMap: env.production, config: { path: root('postcss.config.js') } },
};
}
function fileLoader() {
return {
loader: 'file-loader',
options: { name: '[path][name].[ext]?[sha1:hash:hex:10]' },
};
}
function extractCssLoader() {
return {
loader: ExtractCssPlugin.loader,
// FIXME auto?
options: {
publicPath: '',
},
};
}
const config = {
bail: true,
mode: env.production ? 'production' : 'development',
profile: true,
context: root(),
entry: {
hydro: './entry.js',
'theme.default': './theme/default.js',
},
output: {
path: root('public'),
publicPath: '/', // overwrite in entry.js
hashFunction: 'sha1',
hashDigest: 'hex',
hashDigestLength: 10,
filename: '[name].js?[chunkhash]',
chunkFilename: '[name].chunk.js?[chunkhash]',
},
resolve: {
modules: [root('node_modules'), root('../../node_modules')],
extensions: ['.js', '.jsx'],
alias: { vj: root() },
},
module: {
rules: [
{
test: /\.(svg|ttf|eot|woff|woff2|png|jpg|jpeg|gif)$/,
use: [fileLoader()],
},
{
test: /\.jsx?$/,
exclude: /node_modules[/\\]/,
use: [babelLoader()],
},
{
test: /\.styl$/,
use: [extractCssLoader(), cssLoader(), postcssLoader(), 'stylus-loader'],
},
{
test: /\.css$/,
use: [extractCssLoader(), cssLoader(), postcssLoader()],
},
],
},
optimization: {
splitChunks: {
minChunks: 2,
},
},
plugins: [
new webpack.ProgressPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
katex: 'katex/dist/katex.js',
React: 'react',
}),
new ExtractCssPlugin({
filename: '[name].css?[contenthash:10]',
}),
new webpack.LoaderOptionsPlugin({
test: /\.styl$/,
stylus: {
default: {
preferPathResolver: 'webpack',
use: [require('rupture')()], // eslint-disable-line global-require
import: ['~vj/common/common.inc.styl'],
},
},
}),
new FriendlyErrorsPlugin(),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new CopyWebpackPlugin({
patterns: [
{ from: root('static') },
{ from: root(dirname(require.resolve('emojify.js/package.json')) + '/dist/images/basic'), to: 'img/emoji/' },
],
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: env.production ? '"production"' : '"debug"',
},
}),
...env.production
? [
new OptimizeCssAssetsPlugin(),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.LoaderOptionsPlugin({ minimize: true }),
new webpack.HashedModuleIdsPlugin(),
]
: [new webpack.NamedModulesPlugin()],
new webpack.LoaderOptionsPlugin({
options: {
context: root(),
customInterpolateName: (url) => beautifyOutputUrl(url),
},
}),
new MonacoWebpackPlugin({
// available options are documented at https://github.com/Microsoft/monaco-editor-webpack-plugin#options
languages: ['cpp', 'csharp', 'java', 'javascript', 'python', 'rust', 'ruby', 'php', 'pascal', 'go'],
}),
new StaticManifestPlugin({
fileName: 'static-manifest.json',
ignore: [
'img/emoji/',
'katex/',
],
}),
...env.measure ? [new BundleAnalyzerPlugin({ analyzerPort: 'auto' })] : [],
],
};
return env.measure ? smp.wrap(config) : config;
}