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

@@ -0,0 +1,27 @@
import through from 'through2';
import nunjucks from 'nunjucks';
export default function compile(data, options = {}) {
return through.obj(function (file, encoding, callback) {
if (file.isNull()) {
callback(null, file);
return;
}
const context = { ...data, ...file.data };
const filePath = file.path;
const env = options.env || new nunjucks.Environment(new nunjucks.FileSystemLoader(file.base), options);
if (options.filters && !options.env) {
for (const key of Object.keys(options.filters)) {
env.addFilter(key, options.filters[key]);
}
}
try {
file.contents = Buffer.from(env.renderString(file.contents.toString(), context));
file.extname = '.styl';
this.push(file);
} catch (error) {
this.emit('error', new Error(`gulp-nunjucks ${error} ${filePath}`));
}
callback();
});
}
@@ -0,0 +1,35 @@
/* eslint-disable import/no-extraneous-dependencies */
import PluginError from 'plugin-error';
import through from 'through2';
import fs from 'fs-extra';
export default function touch(mtime) {
async function touchFile(file) {
const fd = await fs.open(file.path, 'a');
try {
await fs.futimes(fd, mtime, mtime);
} finally {
await fs.close(fd);
}
}
function processStream(file, encoding, callback) {
if (file.isNull()) {
callback();
return;
}
if (file.isStream()) {
this.emit('error', new PluginError('gulpTouch', 'Stream not supported'));
callback();
return;
}
touchFile(file)
.catch((err) => this.emit('error', err))
.then(() => {
this.push(file);
callback();
});
}
return through.obj(processStream);
}
@@ -0,0 +1,49 @@
/* eslint-disable import/no-extraneous-dependencies */
const _ = require('lodash');
const crypto = require('crypto');
export default class StaticManifestPlugin {
constructor({ fileName, ignore }) {
this.fileName = fileName;
this.ignore = ignore;
}
apply(compiler) {
compiler.hooks.emit.tap('sync', (compilation) => {
const stats = compilation.getStats().toJson();
const manifest = _(stats.assets)
.map((asset) => {
const { name } = asset;
// Skip files listed in ignore
if (_.some(this.ignore, (ignorePattern) => name.indexOf(ignorePattern) > -1)) {
return null;
}
// Skip calculating hash for names like ?xxxx
if (name.indexOf('?') > -1) {
return [
name.replace(/\?[\s\S]*/, ''), // origin name
name, // name with hash
];
}
// We need to calculate hash for the remaining files.
const source = compilation.assets[asset.name].source();
const shasum = crypto.createHash('sha1');
shasum.update(source);
const hash = shasum.digest('hex').substr(0, 10);
return [
name, // origin name
`${name}?${hash}`, // name with hash
];
})
.filter()
.orderBy(['0'])
.fromPairs()
.value();
const json = JSON.stringify(manifest, null, 2);
compilation.assets[this.fileName] = {
source: () => json,
size: () => json.length,
};
});
}
}
@@ -0,0 +1,23 @@
module.exports = function () {
return {
name: 'provide-plugin',
async transform({ id, fileExt, contents }) {
if (fileExt !== '.js' && fileExt !== '.jsx') return contents;
if (id.includes('/node_modules/jquery.transit/')) {
return `import jQuery from 'jquery'\n${contents.replace('this, function', '{jQuery}, function')}`;
}
if (id.includes('/node_modules/sticky-kit/')) {
return `import jQuery from 'jquery'\n${contents.replace('$ = this.jQuery || window.jQuery;', '$ = jQuery;')}`;
}
if (id.includes('/node_modules/')) {
if (!/\/(jquery-scroll-lock|jquery\.easing|jquery\.transit)\//.test(id)) return { contents };
}
if (contents.includes('$(')) contents = `import $ from 'jquery';\n${contents}`;
if (contents.includes('jQuery')) contents = `import jQuery from 'jquery';\n${contents}`;
if (!contents.includes('import React')) {
if (contents.includes('React.') || fileExt === '.jsx') contents = `import React from 'react';\n${contents}`;
}
return contents.replace(/process\.env/g, 'import.meta.env');
},
};
};
@@ -0,0 +1,216 @@
const acorn = require('acorn');
const stage3 = require('acorn-stage3');
const walk = require('acorn-walk');
const astring = require('astring');
const path = require('path');
const fsp = require('fs').promises;
const dirWatchers = {};
const parser = acorn.Parser.extend(stage3);
async function requireContext(filePath) {
const source = await fsp.readFile(filePath, 'utf8');
if (!/\brequire\s*\.\s*context\s*\(/.test(source)) {
delete dirWatchers[filePath];
return null;
}
const ast = parser.parse(source,
{ sourceType: 'module', ecmaVersion: 'latest', locations: true });
const base = path.dirname(path.resolve(filePath));
const nodes = [];
walk.simple(ast, {
CallExpression(node) {
const { callee } = node;
const args = node.arguments;
if (callee.type !== 'MemberExpression') return;
if (callee.object.name !== 'require') return;
if (callee.property.name !== 'context') return;
if (args.length === 0) return;
if (!args.every((arg) => arg.type === 'Literal')) return;
if (args.length > 2 && !args[2].regex) return;
nodes.push(node);
},
});
if (nodes.length === 0) {
delete dirWatchers[filePath];
return null;
}
const imports = [];
const dirs = [];
await Promise.all(nodes.map(async (node) => {
const args = node.arguments;
const directory = path.resolve(base, args[0].value);
const recurse = args[1] && args[1].value;
const regExp = args[2] && new RegExp(args[2].regex.pattern, args[2].regex.flags);
dirs.push(directory);
async function getFiles(dir, recurse, pattern) {
try {
const dirents = await fsp.readdir(dir, { withFileTypes: true });
const files = await Promise.all(dirents.map((dirent) => {
const res = path.resolve(dir, dirent.name);
if (dirent.isDirectory()) {
return (recurse !== false) && getFiles(res);
}
return (!pattern || pattern.test(res)) ? res : null;
}));
return Array.prototype.concat(...files);
} catch (error) {
if (error.code === 'ENOENT') return [];
throw error;
}
}
const files = (await getFiles(directory, recurse, regExp))
.filter((file) => file).map((file) => {
file = path.relative(base, file);
if (!file.startsWith('/') && !file.startsWith('.')) file = `./${file}`;
return file;
});
const modules = files.map((file) => Math.random().toString(36).slice(2).replace(/\d/g, '') + file.split('/').pop().split('.')[0]
.replace(/^\w/, (c) => c.toUpperCase())
.replace(/[-_]\w/g, (c) => c[1].toUpperCase()).replace(/\W/g, '$'));
files.forEach((file, i) => {
imports.push({
type: 'ImportDeclaration',
specifiers: [
{
type: 'ImportDefaultSpecifier',
local: { type: 'Identifier', name: modules[i] },
},
],
source: { type: 'Literal', value: file, raw: JSON.stringify(file) },
});
});
const keys = files.map((file) => `./${path.relative(directory, path.resolve(base, file))}`);
const contextKeys = {
type: 'ArrayExpression',
elements: keys.map((file) => (
{ type: 'Literal', value: file, raw: JSON.stringify(file) }
)),
};
const contextMap = {
type: 'ObjectExpression',
properties: keys.map((key, i) => ({
type: 'Property',
method: false,
shorthand: false,
computed: false,
key: { type: 'Literal', value: key, raw: JSON.stringify(key) },
value: {
type: 'ObjectExpression',
properties: [{
type: 'Property',
method: false,
shorthand: false,
computed: false,
key: { type: 'Identifier', name: 'default' },
value: { type: 'Identifier', name: modules[i] },
kind: 'init',
}],
},
kind: 'init',
})),
};
const contextFn = {
type: 'VariableDeclaration',
declarations: [
{
type: 'VariableDeclarator',
id: { type: 'Identifier', name: 'context' },
init: {
type: 'ArrowFunctionExpression',
id: null,
expression: true,
generator: false,
async: false,
params: [{ type: 'Identifier', name: 'id' }],
body: {
type: 'MemberExpression',
object: contextMap,
property: { type: 'Identifier', name: 'id' },
computed: true,
optional: false,
},
},
},
],
kind: 'let',
};
const keyFn = {
type: 'ExpressionStatement',
expression: {
type: 'AssignmentExpression',
operator: '=',
left: {
type: 'MemberExpression',
object: { type: 'Identifier', name: 'context' },
property: { type: 'Identifier', name: 'keys' },
computed: false,
optional: false,
},
right: {
type: 'ArrowFunctionExpression',
id: null,
expression: true,
generator: false,
async: false,
params: [],
body: contextKeys,
},
},
};
const contextExpr = {
type: 'CallExpression',
callee: {
type: 'ArrowFunctionExpression',
id: null,
expression: false,
generator: false,
async: false,
params: [],
body: {
type: 'BlockStatement',
body: [
contextFn,
keyFn,
{
type: 'ReturnStatement',
argument: {
type: 'Identifier',
name: 'context',
},
},
],
},
},
arguments: [],
optional: false,
};
delete node.callee;
delete node.arguments;
delete node.optional;
Object.assign(node, contextExpr);
}));
ast.body.unshift(...imports);
dirWatchers[filePath] = dirs;
return astring.generate(ast);
}
module.exports = function (snowpackConfig, pluginOptions) {
return {
name: 'require-context-plugin',
resolve: {
input: Array.from(pluginOptions.input || ['.js']),
output: ['.js'],
},
onChange({ filePath }) {
for (const [source, dirs] of Object.entries(dirWatchers)) {
if (dirs.some((dir) => filePath.startsWith(dir))) {
this.markChanged(source);
}
}
},
load({ filePath }) {
return requireContext(filePath);
},
};
};