├── test-ts ├── src │ ├── app.ts │ ├── t.wxts │ ├── x.wxss │ └── app.wxss └── tsconfig.json ├── test-empty └── src │ ├── app.js │ ├── app.wxss │ ├── app.json │ └── pages │ ├── index.wxml │ └── index.wxss ├── test ├── src │ ├── wxss │ │ ├── empty.scss │ │ ├── a.wxss │ │ ├── npm.scss │ │ └── inline.scss │ ├── lib │ │ ├── test.ts │ │ └── t.js │ ├── wxs │ │ ├── x.wxts │ │ └── comm.wxts │ ├── assets │ │ ├── mixins │ │ │ └── _f.scss │ │ ├── b.wxss.scss │ │ ├── _a.scss │ │ ├── _t.scss │ │ └── images │ │ │ ├── img.png │ │ │ ├── test.svg │ │ │ └── arrow-up.svg │ ├── icons │ │ ├── img.png │ │ └── uEA01-arrow-down.svg │ ├── app.jsonc │ ├── pages │ │ └── index │ │ │ ├── index.scss │ │ │ ├── index.ts │ │ │ └── index.html │ ├── project.config.jsonc │ ├── app.ts │ └── app.scss ├── .mpconfig.jsonc ├── package.json ├── .svgo.yml └── tsconfig.json ├── CNAME ├── vendor └── clean-css │ ├── options │ ├── rebase.js │ ├── inline-timeout.js │ ├── rebase-to.js │ ├── fetch.js │ ├── inline.js │ ├── inline-request.js │ ├── rounding-precision.js │ └── compatibility.js │ ├── reader │ ├── restore-import.js │ ├── match-data-uri.js │ ├── normalize-path.js │ ├── rebase-remote-map.js │ ├── rebase-local-map.js │ ├── extract-import-url-and-media.js │ ├── input-source-map-tracker.js │ ├── load-remote-resource.js │ ├── is-allowed-resource.js │ ├── rebase.js │ ├── rewrite-url.js │ └── load-original-sources.js │ ├── optimizer │ ├── hack.js │ ├── level-0 │ │ └── optimize.js │ ├── level-1 │ │ ├── tidy-at-rule.js │ │ ├── shorten-rgb.js │ │ ├── sort-selectors.js │ │ ├── tidy-block.js │ │ ├── shorten-hsl.js │ │ └── shorten-hex.js │ ├── level-2 │ │ ├── properties │ │ │ ├── has-inherit.js │ │ │ ├── is-mergeable-shorthand.js │ │ │ ├── overrides-non-component-shorthand.js │ │ │ ├── understandable.js │ │ │ ├── vendor-prefixes.js │ │ │ ├── is-component-of.js │ │ │ ├── every-values-pair.js │ │ │ ├── find-component-in.js │ │ │ ├── populate-components.js │ │ │ └── optimize.js │ │ ├── invalid-property-error.js │ │ ├── restore-with-components.js │ │ ├── tidy-rule-duplicates.js │ │ ├── rules-overlap.js │ │ ├── remove-duplicate-font-at-rules.js │ │ ├── remove-duplicate-media-queries.js │ │ ├── clone.js │ │ ├── specificities-overlap.js │ │ ├── remove-duplicates.js │ │ ├── extract-properties.js │ │ ├── merge-adjacent.js │ │ ├── specificity.js │ │ ├── merge-non-adjacent-by-selector.js │ │ ├── merge-non-adjacent-by-body.js │ │ ├── merge-media-queries.js │ │ ├── reorderable.js │ │ └── optimize.js │ ├── remove-unused.js │ └── restore-from-optimizing.js │ ├── utils │ ├── is-import.js │ ├── has-protocol.js │ ├── is-http-resource.js │ ├── is-https-resource.js │ ├── is-remote-resource.js │ ├── is-data-uri-resource.js │ ├── format-position.js │ ├── clone-array.js │ ├── override.js │ ├── natural-compare.js │ └── split.js │ ├── tokenizer │ ├── marker.js │ └── token.js │ └── writer │ ├── one-time.js │ ├── simple.js │ └── source-maps.js ├── src ├── lib │ ├── empty.js │ ├── byte-counter.js │ ├── inline.js │ ├── npm-install.js │ ├── package-var.js │ ├── pretty-bytes.js │ ├── ext-to-glob.js │ ├── json-mini.js │ ├── pretty-time.js │ ├── unlink.js │ ├── rollup-plugins.js │ ├── clean-css.js │ ├── multi-replace.js │ ├── wxss-importer.js │ └── image-min.js ├── log │ ├── task-log.js │ ├── watch.js │ ├── rainbow.js │ ├── color.js │ ├── error.js │ ├── warn.js │ ├── logger.js │ ├── compile.js │ └── size.js ├── compiler │ ├── copy.js │ ├── compress-image.js │ ├── compile-javascript.js │ ├── compile-json.js │ ├── compress-wxml.js │ ├── compile-typescript.js │ ├── compile-wxts.js │ └── build-npm.js ├── tasks │ ├── clean.js │ ├── wxml.js │ ├── json.js │ ├── image.js │ ├── javascript.js │ ├── copy.js │ ├── wxss.js │ ├── typescript.js │ ├── wxts.js │ └── npm.js ├── config.js └── task.js ├── .travis.yml ├── .github └── workflows │ ├── nodejs.yml │ ├── beta.yml │ └── npmpublish.yml ├── LICENSE ├── .gitignore ├── config.schema.json └── package.json /test-ts/src/app.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-ts/src/t.wxts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-ts/src/x.wxss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-empty/src/app.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-empty/src/app.wxss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-empty/src/app.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /test/src/wxss/empty.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-empty/src/pages/index.wxml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | miniprogram-build.newfuture.cc -------------------------------------------------------------------------------- /test-ts/src/app.wxss: -------------------------------------------------------------------------------- 1 | @import "/x.wxss" -------------------------------------------------------------------------------- /test/src/lib/test.ts: -------------------------------------------------------------------------------- 1 | export const test={}; -------------------------------------------------------------------------------- /test/src/wxs/x.wxts: -------------------------------------------------------------------------------- 1 | export const x = ()=>1; -------------------------------------------------------------------------------- /test/src/wxss/a.wxss: -------------------------------------------------------------------------------- 1 | test-a{ 2 | scale: 0; 3 | } -------------------------------------------------------------------------------- /test/src/lib/t.js: -------------------------------------------------------------------------------- 1 | var a = 1; 2 | var id = '{{APP_ID}}' 3 | -------------------------------------------------------------------------------- /test/src/assets/mixins/_f.scss: -------------------------------------------------------------------------------- 1 | @mixin f { 2 | width: 10%; 3 | } -------------------------------------------------------------------------------- /test-empty/src/pages/index.wxss: -------------------------------------------------------------------------------- 1 | .a { 2 | border: 2rpx solid green; 3 | } 4 | -------------------------------------------------------------------------------- /test/src/assets/b.wxss.scss: -------------------------------------------------------------------------------- 1 | .b{ 2 | content: 'include'; 3 | color:'red'; 4 | } -------------------------------------------------------------------------------- /test/src/wxss/npm.scss: -------------------------------------------------------------------------------- 1 | @import "~weui-wxss"; 2 | @import "~weui-wxss/dist/style/weui.wxss"; 3 | -------------------------------------------------------------------------------- /test/src/assets/_a.scss: -------------------------------------------------------------------------------- 1 | .avatar{ 2 | background-image: url(images/img.png)//./images/img.png); 3 | } -------------------------------------------------------------------------------- /test/src/icons/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewFuture/miniprogram-build/HEAD/test/src/icons/img.png -------------------------------------------------------------------------------- /test/src/assets/_t.scss: -------------------------------------------------------------------------------- 1 | a{ 2 | color: aqua; 3 | background: url(/src/assets/images/arrow-up.svg) 4 | } -------------------------------------------------------------------------------- /test/src/app.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | 注释 4 | */ 5 | "appid": "{{APP_ID}}", //APPID, 6 | "test": 2, 7 | } -------------------------------------------------------------------------------- /test/src/assets/images/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewFuture/miniprogram-build/HEAD/test/src/assets/images/img.png -------------------------------------------------------------------------------- /test/src/pages/index/index.scss: -------------------------------------------------------------------------------- 1 | @import 't'; 2 | @import 'mixins/f'; 3 | @import 'a'; 4 | 5 | .x{ 6 | @include f; 7 | } -------------------------------------------------------------------------------- /test/src/pages/index/index.ts: -------------------------------------------------------------------------------- 1 | import { test } from "/lib/test"; 2 | 3 | console.log(test); 4 | Page({ 5 | 6 | 7 | }) -------------------------------------------------------------------------------- /test/src/wxss/inline.scss: -------------------------------------------------------------------------------- 1 | .b{ 2 | padding-top: 0%; 3 | padding-left: 0%; 4 | padding-right: 0%; 5 | padding-bottom: 0%; 6 | } -------------------------------------------------------------------------------- /vendor/clean-css/options/rebase.js: -------------------------------------------------------------------------------- 1 | function rebaseFrom(rebaseOption) { 2 | return undefined === rebaseOption ? true : !!rebaseOption; 3 | } 4 | 5 | module.exports = rebaseFrom; 6 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/restore-import.js: -------------------------------------------------------------------------------- 1 | function restoreImport(uri, mediaQuery) { 2 | return ('@import ' + uri + ' ' + mediaQuery).trim(); 3 | } 4 | 5 | module.exports = restoreImport; 6 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/hack.js: -------------------------------------------------------------------------------- 1 | var Hack = { 2 | ASTERISK: 'asterisk', 3 | BANG: 'bang', 4 | BACKSLASH: 'backslash', 5 | UNDERSCORE: 'underscore' 6 | }; 7 | 8 | module.exports = Hack; 9 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-0/optimize.js: -------------------------------------------------------------------------------- 1 | function level0Optimize(tokens) { 2 | // noop as level 0 means no optimizations! 3 | return tokens; 4 | } 5 | 6 | module.exports = level0Optimize; 7 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/is-import.js: -------------------------------------------------------------------------------- 1 | var IMPORT_PREFIX_PATTERN = /^@import/i; 2 | 3 | function isImport(value) { 4 | return IMPORT_PREFIX_PATTERN.test(value); 5 | } 6 | 7 | module.exports = isImport; 8 | -------------------------------------------------------------------------------- /vendor/clean-css/options/inline-timeout.js: -------------------------------------------------------------------------------- 1 | var DEFAULT_TIMEOUT = 5000; 2 | 3 | function inlineTimeoutFrom(option) { 4 | return option || DEFAULT_TIMEOUT; 5 | } 6 | 7 | module.exports = inlineTimeoutFrom; 8 | -------------------------------------------------------------------------------- /vendor/clean-css/options/rebase-to.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | function rebaseToFrom(option) { 4 | return option ? path.resolve(option) : process.cwd(); 5 | } 6 | 7 | module.exports = rebaseToFrom; 8 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/has-protocol.js: -------------------------------------------------------------------------------- 1 | var NO_PROTOCOL_RESOURCE_PATTERN = /^\/\//; 2 | 3 | function hasProtocol(uri) { 4 | return !NO_PROTOCOL_RESOURCE_PATTERN.test(uri); 5 | } 6 | 7 | module.exports = hasProtocol; 8 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/is-http-resource.js: -------------------------------------------------------------------------------- 1 | var HTTP_RESOURCE_PATTERN = /^http:\/\//; 2 | 3 | function isHttpResource(uri) { 4 | return HTTP_RESOURCE_PATTERN.test(uri); 5 | } 6 | 7 | module.exports = isHttpResource; 8 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/is-https-resource.js: -------------------------------------------------------------------------------- 1 | var HTTPS_RESOURCE_PATTERN = /^https:\/\//; 2 | 3 | function isHttpsResource(uri) { 4 | return HTTPS_RESOURCE_PATTERN.test(uri); 5 | } 6 | 7 | module.exports = isHttpsResource; 8 | -------------------------------------------------------------------------------- /vendor/clean-css/options/fetch.js: -------------------------------------------------------------------------------- 1 | var loadRemoteResource = require('../reader/load-remote-resource'); 2 | 3 | function fetchFrom(callback) { 4 | return callback || loadRemoteResource; 5 | } 6 | 7 | module.exports = fetchFrom; 8 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/is-remote-resource.js: -------------------------------------------------------------------------------- 1 | var REMOTE_RESOURCE_PATTERN = /^(\w+:\/\/|\/\/)/; 2 | 3 | function isRemoteResource(uri) { 4 | return REMOTE_RESOURCE_PATTERN.test(uri); 5 | } 6 | 7 | module.exports = isRemoteResource; 8 | -------------------------------------------------------------------------------- /test/src/project.config.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件", 3 | "packOptions": { 4 | "ignore": [], 5 | }, 6 | "compileType": "miniprogram", 7 | "libVersion": "2.7.0", 8 | "projectname": "{{PROJECT_NAME}}", 9 | } -------------------------------------------------------------------------------- /vendor/clean-css/reader/match-data-uri.js: -------------------------------------------------------------------------------- 1 | var DATA_URI_PATTERN = /^data:(\S*?)?(;charset=[^;]+)?(;[^,]+?)?,(.+)/; 2 | 3 | function matchDataUri(uri) { 4 | return DATA_URI_PATTERN.exec(uri); 5 | } 6 | 7 | module.exports = matchDataUri; 8 | -------------------------------------------------------------------------------- /test/.mpconfig.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | // "a": "[1,2,3,]", 3 | "var": { 4 | "APP_ID": "123456", //APPID 5 | "VERSION": "{{package.version}}", 6 | "Vx": "{{packa}}", 7 | "THEME_COLOR": "#fcc", 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /src/lib/empty.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 'use strict'; 3 | 4 | var through = require("through2"); 5 | function empty() { 6 | return through.obj(function (file, enc, cb) { 7 | cb(null, file); 8 | }); 9 | } 10 | module.exports = empty; 11 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/is-data-uri-resource.js: -------------------------------------------------------------------------------- 1 | var DATA_URI_PATTERN = /^data:(\S*?)?(;charset=[^;]+)?(;[^,]+?)?,(.+)/; 2 | 3 | function isDataUriResource(uri) { 4 | return DATA_URI_PATTERN.test(uri); 5 | } 6 | 7 | module.exports = isDataUriResource; 8 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-1/tidy-at-rule.js: -------------------------------------------------------------------------------- 1 | function tidyAtRule(value) { 2 | return value 3 | .replace(/\s+/g, ' ') 4 | .replace(/url\(\s+/g, 'url(') 5 | .replace(/\s+\)/g, ')') 6 | .trim(); 7 | } 8 | 9 | module.exports = tidyAtRule; 10 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/normalize-path.js: -------------------------------------------------------------------------------- 1 | var UNIX_SEPARATOR = '/'; 2 | var WINDOWS_SEPARATOR_PATTERN = /\\/g; 3 | 4 | function normalizePath(path) { 5 | return path.replace(WINDOWS_SEPARATOR_PATTERN, UNIX_SEPARATOR); 6 | } 7 | 8 | module.exports = normalizePath; 9 | -------------------------------------------------------------------------------- /src/log/task-log.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var log = require('../log/logger'); 4 | 5 | 6 | module.exports = function () { 7 | var arg = arguments; 8 | return function (cb) { 9 | log.apply(log, arg); 10 | cb && cb(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/src/wxs/comm.wxts: -------------------------------------------------------------------------------- 1 | 2 | import {x} from "./x.wxs"; 3 | 4 | const foo = "'hello world' from comm.wxs" + Date.now(); 5 | const bar = function (d: string) { 6 | return decodeURI(d); 7 | } 8 | 9 | module.exports = { 10 | foo: foo, 11 | bar: bar, 12 | a: "{{APP_ID}}" 13 | }; -------------------------------------------------------------------------------- /test/src/assets/images/test.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | " " '' # % # {} “’ " " '' # % # {} xxx % & ¿ 🔣 6 | 7 | 8 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/has-inherit.js: -------------------------------------------------------------------------------- 1 | function hasInherit(property) { 2 | for (var i = property.value.length - 1; i >= 0; i--) { 3 | if (property.value[i][1] == 'inherit') 4 | return true; 5 | } 6 | 7 | return false; 8 | } 9 | 10 | module.exports = hasInherit; 11 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/format-position.js: -------------------------------------------------------------------------------- 1 | function formatPosition(metadata) { 2 | var line = metadata[0]; 3 | var column = metadata[1]; 4 | var source = metadata[2]; 5 | 6 | return source ? 7 | source + ':' + line + ':' + column : 8 | line + ':' + column; 9 | } 10 | 11 | module.exports = formatPosition; 12 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/remove-unused.js: -------------------------------------------------------------------------------- 1 | function removeUnused(properties) { 2 | for (var i = properties.length - 1; i >= 0; i--) { 3 | var property = properties[i]; 4 | 5 | if (property.unused) { 6 | property.all.splice(property.position, 1); 7 | } 8 | } 9 | } 10 | 11 | module.exports = removeUnused; 12 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/clone-array.js: -------------------------------------------------------------------------------- 1 | function cloneArray(array) { 2 | var cloned = array.slice(0); 3 | 4 | for (var i = 0, l = cloned.length; i < l; i++) { 5 | if (Array.isArray(cloned[i])) 6 | cloned[i] = cloneArray(cloned[i]); 7 | } 8 | 9 | return cloned; 10 | } 11 | 12 | module.exports = cloneArray; 13 | -------------------------------------------------------------------------------- /test/src/app.ts: -------------------------------------------------------------------------------- 1 | import { test } from "/lib/test"; 2 | import {request} from "miniprogram-network" 3 | test 4 | const data = { 5 | 6 | 7 | appId: "{{APP_ID}}", 8 | version: "{{VERSION}}", 9 | }; 10 | App({ 11 | 12 | onLaunch() { 13 | request("POST","/"); 14 | console.log(test, "{{Vx}}"); 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /vendor/clean-css/options/inline.js: -------------------------------------------------------------------------------- 1 | function inlineOptionsFrom(rules) { 2 | if (Array.isArray(rules)) { 3 | return rules; 4 | } 5 | 6 | if (rules === false) { 7 | return ['none']; 8 | } 9 | 10 | return undefined === rules ? 11 | ['local'] : 12 | rules.split(','); 13 | } 14 | 15 | module.exports = inlineOptionsFrom; 16 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/is-mergeable-shorthand.js: -------------------------------------------------------------------------------- 1 | var Marker = require('../../../tokenizer/marker'); 2 | 3 | function isMergeableShorthand(shorthand) { 4 | if (shorthand.name != 'font') { 5 | return true; 6 | } 7 | 8 | return shorthand.value[0][1].indexOf(Marker.INTERNAL) == -1; 9 | } 10 | 11 | module.exports = isMergeableShorthand; 12 | -------------------------------------------------------------------------------- /src/log/watch.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var colors = require('ansi-colors'); 4 | var log = require('../log/logger'); 5 | 6 | /** 7 | * @param {string} name 8 | */ 9 | module.exports = function (name, files) { 10 | process.env.SKIP_ERROR = 'true'; 11 | return log.info( 12 | colors.magentaBright(name + '-watch:'), 13 | colors.underline.blueBright(files) 14 | ); 15 | } -------------------------------------------------------------------------------- /test/src/pages/index/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/invalid-property-error.js: -------------------------------------------------------------------------------- 1 | function InvalidPropertyError(message) { 2 | this.name = 'InvalidPropertyError'; 3 | this.message = message; 4 | this.stack = (new Error()).stack; 5 | } 6 | 7 | InvalidPropertyError.prototype = Object.create(Error.prototype); 8 | InvalidPropertyError.prototype.constructor = InvalidPropertyError; 9 | 10 | module.exports = InvalidPropertyError; 11 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/restore-with-components.js: -------------------------------------------------------------------------------- 1 | var compactable = require('./compactable'); 2 | 3 | function restoreWithComponents(property) { 4 | var descriptor = compactable[property.name]; 5 | 6 | if (descriptor && descriptor.shorthand) { 7 | return descriptor.restore(property, compactable); 8 | } else { 9 | return property.value; 10 | } 11 | } 12 | 13 | module.exports = restoreWithComponents; 14 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/rebase-remote-map.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var url = require('url'); 3 | 4 | function rebaseRemoteMap(sourceMap, sourceUri) { 5 | var sourceDirectory = path.dirname(sourceUri); 6 | 7 | sourceMap.sources = sourceMap.sources.map(function(source) { 8 | return url.resolve(sourceDirectory, source); 9 | }); 10 | 11 | return sourceMap; 12 | } 13 | 14 | module.exports = rebaseRemoteMap; 15 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/overrides-non-component-shorthand.js: -------------------------------------------------------------------------------- 1 | var compactable = require('../compactable'); 2 | 3 | function overridesNonComponentShorthand(property1, property2) { 4 | return property1.name in compactable && 5 | 'overridesShorthands' in compactable[property1.name] && 6 | compactable[property1.name].overridesShorthands.indexOf(property2.name) > -1; 7 | } 8 | 9 | module.exports = overridesNonComponentShorthand; 10 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/understandable.js: -------------------------------------------------------------------------------- 1 | var sameVendorPrefixes = require('./vendor-prefixes').same; 2 | 3 | function understandable(validator, value1, value2, _position, isPaired) { 4 | if (!sameVendorPrefixes(value1, value2)) { 5 | return false; 6 | } 7 | 8 | if (isPaired && validator.isVariable(value1) !== validator.isVariable(value2)) { 9 | return false; 10 | } 11 | 12 | return true; 13 | } 14 | 15 | module.exports = understandable; 16 | -------------------------------------------------------------------------------- /src/lib/byte-counter.js: -------------------------------------------------------------------------------- 1 | // https://github.com/andrewrk/node-stream-counter 2 | 3 | module.exports = ByteCounter; 4 | 5 | var Writable = require('stream').Writable; 6 | var util = require('util'); 7 | 8 | util.inherits(ByteCounter, Writable); 9 | function ByteCounter(options) { 10 | Writable.call(this, options); 11 | this.bytes = 0; 12 | } 13 | 14 | ByteCounter.prototype._write = function(chunk, encoding, cb) { 15 | this.bytes += chunk.length; 16 | this.emit('progress'); 17 | cb(); 18 | }; -------------------------------------------------------------------------------- /src/compiler/copy.js: -------------------------------------------------------------------------------- 1 | 2 | ///@ts-check 3 | 'use strict'; 4 | var gulp = require('gulp'); 5 | var size = require('../log/size'); 6 | 7 | var TITLE = 'copy:'; 8 | 9 | /** 10 | * 11 | * @param {string} dist 12 | * @param {string|string[]} file 13 | * @param {{base:string,ignore?:any}} opt 14 | */ 15 | function copy(dist, file, opt) { 16 | return gulp.src(file, opt) 17 | .pipe(gulp.dest(dist)) 18 | .pipe(size({ title: TITLE, showFiles: true })) 19 | ; 20 | } 21 | 22 | module.exports = copy; -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-1/shorten-rgb.js: -------------------------------------------------------------------------------- 1 | function shortenRgb(red, green, blue) { 2 | var normalizedRed = Math.max(0, Math.min(parseInt(red), 255)); 3 | var normalizedGreen = Math.max(0, Math.min(parseInt(green), 255)); 4 | var normalizedBlue = Math.max(0, Math.min(parseInt(blue), 255)); 5 | 6 | // Credit: Asen http://jsbin.com/UPUmaGOc/2/edit?js,console 7 | return '#' + ('00000' + (normalizedRed << 16 | normalizedGreen << 8 | normalizedBlue).toString(16)).slice(-6); 8 | } 9 | 10 | module.exports = shortenRgb; 11 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/tidy-rule-duplicates.js: -------------------------------------------------------------------------------- 1 | function ruleSorter(s1, s2) { 2 | return s1[1] > s2[1] ? 1 : -1; 3 | } 4 | 5 | function tidyRuleDuplicates(rules) { 6 | var list = []; 7 | var repeated = []; 8 | 9 | for (var i = 0, l = rules.length; i < l; i++) { 10 | var rule = rules[i]; 11 | 12 | if (repeated.indexOf(rule[1]) == -1) { 13 | repeated.push(rule[1]); 14 | list.push(rule); 15 | } 16 | } 17 | 18 | return list.sort(ruleSorter); 19 | } 20 | 21 | module.exports = tidyRuleDuplicates; 22 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/rebase-local-map.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | function rebaseLocalMap(sourceMap, sourceUri, rebaseTo) { 4 | var currentPath = path.resolve(''); 5 | var absoluteUri = path.resolve(currentPath, sourceUri); 6 | var absoluteUriDirectory = path.dirname(absoluteUri); 7 | 8 | sourceMap.sources = sourceMap.sources.map(function(source) { 9 | return path.relative(rebaseTo, path.resolve(absoluteUriDirectory, source)); 10 | }); 11 | 12 | return sourceMap; 13 | } 14 | 15 | module.exports = rebaseLocalMap; 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | # - "6" 5 | - "8" 6 | - "10" 7 | - "stable" 8 | 9 | # git: 10 | # depth: 1 11 | 12 | # before_deploy: 13 | # - "[[ $TRAVIS_TAG == v* ]] || [[ $TRAVIS_TAG == V* ]]" 14 | # - sed -i "s/^\(\W*version\W*\).*\(\W,\)$/\1${TRAVIS_TAG:1}\2/" package.json 15 | 16 | # deploy: 17 | # - provider: npm 18 | # email: npmjs@newfututre.cc 19 | # api_key: "${NPM_TOKEN}" 20 | # skip_cleanup: true 21 | # on: 22 | # tags: true 23 | # branch: master 24 | # node_js: 'stable' -------------------------------------------------------------------------------- /src/lib/inline.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 'use strict'; 3 | var through = require('through2'); 4 | var inline = require('./inline-image'); 5 | 6 | module.exports = function (opts) { 7 | 8 | function rebase(file, encoding, callback) { 9 | var self = this; 10 | 11 | inline.stylesheet(file, opts, function (err, src) { 12 | if (err) { 13 | console.error(err); 14 | } 15 | file.contents = Buffer.from(src); 16 | 17 | self.push(file); 18 | callback(); 19 | }); 20 | 21 | } 22 | 23 | return through.obj(rebase); 24 | }; -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/vendor-prefixes.js: -------------------------------------------------------------------------------- 1 | var VENDOR_PREFIX_PATTERN = /(?:^|\W)(\-\w+\-)/g; 2 | 3 | function unique(value) { 4 | var prefixes = []; 5 | var match; 6 | 7 | while ((match = VENDOR_PREFIX_PATTERN.exec(value)) !== null) { 8 | if (prefixes.indexOf(match[0]) == -1) { 9 | prefixes.push(match[0]); 10 | } 11 | } 12 | 13 | return prefixes; 14 | } 15 | 16 | function same(value1, value2) { 17 | return unique(value1).sort().join(',') == unique(value2).sort().join(','); 18 | } 19 | 20 | module.exports = { 21 | unique: unique, 22 | same: same 23 | }; 24 | -------------------------------------------------------------------------------- /vendor/clean-css/options/inline-request.js: -------------------------------------------------------------------------------- 1 | var url = require('url'); 2 | 3 | var override = require('../utils/override'); 4 | 5 | function inlineRequestFrom(option) { 6 | return override( 7 | /* jshint camelcase: false */ 8 | proxyOptionsFrom(process.env.HTTP_PROXY || process.env.http_proxy), 9 | option || {} 10 | ); 11 | } 12 | 13 | function proxyOptionsFrom(httpProxy) { 14 | return httpProxy ? 15 | { 16 | hostname: url.parse(httpProxy).hostname, 17 | port: parseInt(url.parse(httpProxy).port) 18 | } : 19 | {}; 20 | } 21 | 22 | module.exports = inlineRequestFrom; 23 | -------------------------------------------------------------------------------- /src/lib/npm-install.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | "use strict"; 3 | var through = require("through2"); 4 | var exec = require("child_process").exec; 5 | 6 | module.exports = function(opts) { 7 | function install(file, encoding, callback) { 8 | exec("npm install --production --no-package-lock --no-bin-links --ignore-scripts --no-audit", opts, function( 9 | err, 10 | stdout, 11 | stderr, 12 | ) { 13 | // console.log(stdout); 14 | console.error(stderr); 15 | callback(err, file); 16 | }); 17 | } 18 | 19 | return through.obj(install); 20 | }; 21 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | node-version: [8.x, 10.x, 12.x] 11 | 12 | steps: 13 | - uses: actions/checkout@v1 14 | - name: Use Node.js ${{ matrix.node-version }} 15 | uses: actions/setup-node@v1 16 | with: 17 | node-version: ${{ matrix.node-version }} 18 | - name: npm install, build, and test 19 | run: | 20 | npm install 21 | npm run build --if-present 22 | npm test 23 | env: 24 | CI: true 25 | -------------------------------------------------------------------------------- /vendor/clean-css/tokenizer/marker.js: -------------------------------------------------------------------------------- 1 | var Marker = { 2 | ASTERISK: '*', 3 | AT: '@', 4 | BACK_SLASH: '\\', 5 | CARRIAGE_RETURN: '\r', 6 | CLOSE_CURLY_BRACKET: '}', 7 | CLOSE_ROUND_BRACKET: ')', 8 | CLOSE_SQUARE_BRACKET: ']', 9 | COLON: ':', 10 | COMMA: ',', 11 | DOUBLE_QUOTE: '"', 12 | EXCLAMATION: '!', 13 | FORWARD_SLASH: '/', 14 | INTERNAL: '-clean-css-', 15 | NEW_LINE_NIX: '\n', 16 | OPEN_CURLY_BRACKET: '{', 17 | OPEN_ROUND_BRACKET: '(', 18 | OPEN_SQUARE_BRACKET: '[', 19 | SEMICOLON: ';', 20 | SINGLE_QUOTE: '\'', 21 | SPACE: ' ', 22 | TAB: '\t', 23 | UNDERSCORE: '_' 24 | }; 25 | 26 | module.exports = Marker; 27 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-1/sort-selectors.js: -------------------------------------------------------------------------------- 1 | var naturalCompare = require('../../utils/natural-compare'); 2 | 3 | function naturalSorter(scope1, scope2) { 4 | return naturalCompare(scope1[1], scope2[1]); 5 | } 6 | 7 | function standardSorter(scope1, scope2) { 8 | return scope1[1] > scope2[1] ? 1 : -1; 9 | } 10 | 11 | function sortSelectors(selectors, method) { 12 | switch (method) { 13 | case 'natural': 14 | return selectors.sort(naturalSorter); 15 | case 'standard': 16 | return selectors.sort(standardSorter); 17 | case 'none': 18 | case false: 19 | return selectors; 20 | } 21 | } 22 | 23 | module.exports = sortSelectors; 24 | -------------------------------------------------------------------------------- /.github/workflows/beta.yml: -------------------------------------------------------------------------------- 1 | name: beta 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | npm-beta: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | - uses: actions/setup-node@v1 14 | with: 15 | registry-url: https://registry.npmjs.org/ 16 | - run: npm i 17 | - run: npm test 18 | - run: sed -i "s/^\(\W*postversion\W*\).*\(\W,\)$/\1cat CHANGELOG.md\2/" package.json 19 | - run: npm version prerelease --no-git-tag-version --no-commit-hooks --preid="beta.${GITHUB_SHA:0:5}" 20 | - run: npm publish --tag beta --access public 21 | env: 22 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 23 | -------------------------------------------------------------------------------- /test/src/app.scss: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | app.scss 4 | */ 5 | //test 6 | @import "./wxss/a.wxss"; // keep as wxss 7 | @import "./wxss/npm.wxss"; // keep as wxss 8 | @import "./assets/b.wxss"; // import scss 9 | @import "./assets/a"; 10 | 11 | 12 | .t{ 13 | background: 14 | url(./assets/images/arrow-up.svg); 15 | width: 20rpx; 16 | } 17 | 18 | $primary-color: '{{THEME_COLOR}}'; 19 | $secondary-color: "{{THEME_COLOR}}"; 20 | 21 | view{ 22 | background: lighten($secondary-color, 90%) 23 | url('./assets/images/test.svg'); 24 | background-color: mix($primary-color, #000); 25 | width: calc(99% -5rpx); 26 | display: flex; 27 | color: '{{THEME_COLOR}}'; 28 | } 29 | 30 | .x{ 31 | width: calc(99% -5rpx); 32 | } 33 | -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "description": "", 4 | "main": "index.js", 5 | "scripts": { 6 | "start": "node ../bin/mp-build.js", 7 | "release": "node ../bin/mp-build.js build -c .mpconfig.jsonc --release", 8 | "pretest": "npm install --no-package-lock --no-bin-links --ignore-scripts --no-audit", 9 | "test": "npm start build --release" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "miniprogram-image": "^1.7.1", 16 | "miniprogram-network": "latest" 17 | }, 18 | "devDependencies": { 19 | "@dragongate/miniprogram-api-typings": "latest", 20 | "weui-wxss": "latest" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/tasks/clean.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | //@ts-check 3 | 'use strict'; 4 | 5 | const path = require('path'); 6 | 7 | const rm = require('rimraf'); 8 | const colors = require('ansi-colors'); 9 | 10 | const log = require('../log/logger'); 11 | const color = require('../log/color'); 12 | 13 | exports.build = function (config) { 14 | return function (cb) { 15 | const projectJson = path.join(config.dist, 'project.config.json') 16 | log(color('clean:'), colors.dim('delete'), colors.bold(config.dist), colors.dim.gray(`[exclude: ${projectJson}]`)); 17 | rm(`${config.dist}/**/*`, { 18 | glob: { 19 | ignore: [projectJson] 20 | } 21 | }, cb); 22 | // return (config.dist); 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/compiler/compress-image.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var gulp = require('gulp'); 4 | var imagemin = require('../lib/image-min'); 5 | var err = require('../log/error'); 6 | const size = require('../log/size'); 7 | 8 | var TITLE = 'image'; 9 | /** 10 | * 11 | * @param {string|string[]} imgsrc 12 | * @param {string} dist 13 | * @param {{base:string,ignore?:any}} opt 14 | * 15 | */ 16 | function compressImage(imgsrc, dist, opt) { 17 | return gulp.src(imgsrc, opt) 18 | // .pipe(debug({ title: 'image:' })) 19 | .pipe(imagemin({ verbose: true })) 20 | .on('error', err(TITLE)) 21 | .pipe(gulp.dest(dist)) 22 | .pipe(size({ title: TITLE, showFiles: false })); 23 | 24 | } 25 | 26 | 27 | module.exports = compressImage -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/rules-overlap.js: -------------------------------------------------------------------------------- 1 | var MODIFIER_PATTERN = /\-\-.+$/; 2 | 3 | function rulesOverlap(rule1, rule2, bemMode) { 4 | var scope1; 5 | var scope2; 6 | var i, l; 7 | var j, m; 8 | 9 | for (i = 0, l = rule1.length; i < l; i++) { 10 | scope1 = rule1[i][1]; 11 | 12 | for (j = 0, m = rule2.length; j < m; j++) { 13 | scope2 = rule2[j][1]; 14 | 15 | if (scope1 == scope2) { 16 | return true; 17 | } 18 | 19 | if (bemMode && withoutModifiers(scope1) == withoutModifiers(scope2)) { 20 | return true; 21 | } 22 | } 23 | } 24 | 25 | return false; 26 | } 27 | 28 | function withoutModifiers(scope) { 29 | return scope.replace(MODIFIER_PATTERN, ''); 30 | } 31 | 32 | module.exports = rulesOverlap; 33 | -------------------------------------------------------------------------------- /src/log/rainbow.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | 4 | const colors = require('ansi-colors'); 5 | 6 | const rainbowColors = [ 7 | 'red', 8 | 'yellowBright', 9 | 'green', 10 | 'blue', 11 | "cyan", 12 | 'magentaBright', 13 | "whiteBright", 14 | // "magentaBright", 15 | "redBright" 16 | ]; 17 | 18 | function colorize(exploded, letter, i) { 19 | if (letter === ' ') { 20 | return exploded + letter; 21 | } else { 22 | return exploded + colors[rainbowColors[i++ % rainbowColors.length]](letter); 23 | } 24 | }; 25 | module.exports = 26 | /** 27 | * 28 | * @param {string} str 29 | * @returns {string} 30 | */ 31 | function rainbow(str) { 32 | return Array.from(str).reduce(colorize, ''); 33 | } -------------------------------------------------------------------------------- /src/lib/package-var.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | const npm = require('./npm-dependency'); 4 | const logger = require('../log/logger'); 5 | 6 | const REG_VAR = /\{\{package.([\w\d]*?)\}\}/g; 7 | 8 | /** 9 | * 替换变量 {{package.xx}} from `package.json` 10 | * @param {object} obj 11 | */ 12 | function replaceVar(obj) { 13 | try { 14 | const pkg = npm.loadPackage(process.cwd()); 15 | for (const k in obj) { 16 | if (obj.hasOwnProperty(k) && typeof obj[k] === "string") { 17 | obj[k] = obj[k].replace(REG_VAR, (m, key) => pkg[key]); 18 | } 19 | } 20 | } catch (e) { 21 | logger.warn('package.json load fail:'); 22 | logger.warn(''+e); 23 | } 24 | return obj; 25 | } 26 | 27 | module.exports = replaceVar -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/remove-duplicate-font-at-rules.js: -------------------------------------------------------------------------------- 1 | var Token = require('../../tokenizer/token'); 2 | 3 | var serializeAll = require('../../writer/one-time').all; 4 | 5 | var FONT_FACE_SCOPE = '@font-face'; 6 | 7 | function removeDuplicateFontAtRules(tokens) { 8 | var fontAtRules = []; 9 | var token; 10 | var key; 11 | var i, l; 12 | 13 | for (i = 0, l = tokens.length; i < l; i++) { 14 | token = tokens[i]; 15 | 16 | if (token[0] != Token.AT_RULE_BLOCK && token[1][0][1] != FONT_FACE_SCOPE) { 17 | continue; 18 | } 19 | 20 | key = serializeAll([token]); 21 | 22 | if (fontAtRules.indexOf(key) > -1) { 23 | token[2] = []; 24 | } else { 25 | fontAtRules.push(key); 26 | } 27 | } 28 | } 29 | 30 | module.exports = removeDuplicateFontAtRules; 31 | -------------------------------------------------------------------------------- /test/src/icons/uEA01-arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Artboard 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/lib/pretty-bytes.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | 4 | const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] 5 | 6 | /** 7 | * 8 | * @param {number} number 9 | * @returns {string} 10 | */ 11 | function prettyBytes(number) { 12 | if (!Number.isFinite(number)) { 13 | return 'NAN'; 14 | } 15 | 16 | if (number < 1) { 17 | const numberString = number.toLocaleString(); 18 | return numberString + ' B'; 19 | } 20 | 21 | const exponent = Math.min(Math.floor(Math.log10(number) / 3), UNITS.length - 1); 22 | number = Number((number / (1000 ** exponent)).toPrecision(3)); 23 | const numberString = number.toLocaleString(); 24 | 25 | const unit = UNITS[exponent]; 26 | 27 | return numberString + ' ' + unit; 28 | }; 29 | 30 | module.exports = prettyBytes; -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-1/tidy-block.js: -------------------------------------------------------------------------------- 1 | var SUPPORTED_COMPACT_BLOCK_MATCHER = /^@media\W/; 2 | 3 | function tidyBlock(values, spaceAfterClosingBrace) { 4 | var withoutSpaceAfterClosingBrace; 5 | var i; 6 | 7 | for (i = values.length - 1; i >= 0; i--) { 8 | withoutSpaceAfterClosingBrace = !spaceAfterClosingBrace && SUPPORTED_COMPACT_BLOCK_MATCHER.test(values[i][1]); 9 | 10 | values[i][1] = values[i][1] 11 | .replace(/\n|\r\n/g, ' ') 12 | .replace(/\s+/g, ' ') 13 | .replace(/(,|:|\() /g, '$1') 14 | .replace(/ \)/g, ')') 15 | .replace(/'([a-zA-Z][a-zA-Z\d\-_]+)'/, '$1') 16 | .replace(/"([a-zA-Z][a-zA-Z\d\-_]+)"/, '$1') 17 | .replace(withoutSpaceAfterClosingBrace ? /\) /g : null, ')'); 18 | } 19 | 20 | return values; 21 | } 22 | 23 | module.exports = tidyBlock; 24 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/is-component-of.js: -------------------------------------------------------------------------------- 1 | var compactable = require('../compactable'); 2 | 3 | function isComponentOf(property1, property2, shallow) { 4 | return isDirectComponentOf(property1, property2) || 5 | !shallow && !!compactable[property1.name].shorthandComponents && isSubComponentOf(property1, property2); 6 | } 7 | 8 | function isDirectComponentOf(property1, property2) { 9 | var descriptor = compactable[property1.name]; 10 | 11 | return 'components' in descriptor && descriptor.components.indexOf(property2.name) > -1; 12 | } 13 | 14 | function isSubComponentOf(property1, property2) { 15 | return property1 16 | .components 17 | .some(function (component) { 18 | return isDirectComponentOf(component, property2); 19 | }); 20 | } 21 | 22 | module.exports = isComponentOf; 23 | -------------------------------------------------------------------------------- /test/src/assets/images/arrow-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Artboard Copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/remove-duplicate-media-queries.js: -------------------------------------------------------------------------------- 1 | var Token = require('../../tokenizer/token'); 2 | 3 | var serializeAll = require('../../writer/one-time').all; 4 | var serializeRules = require('../../writer/one-time').rules; 5 | 6 | function removeDuplicateMediaQueries(tokens) { 7 | var candidates = {}; 8 | var candidate; 9 | var token; 10 | var key; 11 | var i, l; 12 | 13 | for (i = 0, l = tokens.length; i < l; i++) { 14 | token = tokens[i]; 15 | if (token[0] != Token.NESTED_BLOCK) { 16 | continue; 17 | } 18 | 19 | key = serializeRules(token[1]) + '%' + serializeAll(token[2]); 20 | candidate = candidates[key]; 21 | 22 | if (candidate) { 23 | candidate[2] = []; 24 | } 25 | 26 | candidates[key] = token; 27 | } 28 | } 29 | 30 | module.exports = removeDuplicateMediaQueries; 31 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/override.js: -------------------------------------------------------------------------------- 1 | function override(source1, source2) { 2 | var target = {}; 3 | var key1; 4 | var key2; 5 | var item; 6 | 7 | for (key1 in source1) { 8 | item = source1[key1]; 9 | 10 | if (Array.isArray(item)) { 11 | target[key1] = item.slice(0); 12 | } else if (typeof item == 'object' && item !== null) { 13 | target[key1] = override(item, {}); 14 | } else { 15 | target[key1] = item; 16 | } 17 | } 18 | 19 | for (key2 in source2) { 20 | item = source2[key2]; 21 | 22 | if (key2 in target && Array.isArray(item)) { 23 | target[key2] = item.slice(0); 24 | } else if (key2 in target && typeof item == 'object' && item !== null) { 25 | target[key2] = override(target[key2], item); 26 | } else { 27 | target[key2] = item; 28 | } 29 | } 30 | 31 | return target; 32 | } 33 | 34 | module.exports = override; 35 | -------------------------------------------------------------------------------- /vendor/clean-css/tokenizer/token.js: -------------------------------------------------------------------------------- 1 | var Token = { 2 | AT_RULE: 'at-rule', // e.g. `@import`, `@charset` 3 | AT_RULE_BLOCK: 'at-rule-block', // e.g. `@font-face{...}` 4 | AT_RULE_BLOCK_SCOPE: 'at-rule-block-scope', // e.g. `@font-face` 5 | COMMENT: 'comment', // e.g. `/* comment */` 6 | NESTED_BLOCK: 'nested-block', // e.g. `@media screen{...}`, `@keyframes animation {...}` 7 | NESTED_BLOCK_SCOPE: 'nested-block-scope', // e.g. `@media`, `@keyframes` 8 | PROPERTY: 'property', // e.g. `color:red` 9 | PROPERTY_BLOCK: 'property-block', // e.g. `--var:{color:red}` 10 | PROPERTY_NAME: 'property-name', // e.g. `color` 11 | PROPERTY_VALUE: 'property-value', // e.g. `red` 12 | RAW: 'raw', // e.g. anything between /* clean-css ignore:start */ and /* clean-css ignore:end */ comments 13 | RULE: 'rule', // e.g `div > a{...}` 14 | RULE_SCOPE: 'rule-scope' // e.g `div > a` 15 | }; 16 | 17 | module.exports = Token; 18 | -------------------------------------------------------------------------------- /vendor/clean-css/utils/natural-compare.js: -------------------------------------------------------------------------------- 1 | // adapted from http://nedbatchelder.com/blog/200712.html#e20071211T054956 2 | 3 | var NUMBER_PATTERN = /([0-9]+)/; 4 | 5 | function naturalCompare(value1, value2) { 6 | var keys1 = ('' + value1).split(NUMBER_PATTERN).map(tryParseInt); 7 | var keys2 = ('' + value2).split(NUMBER_PATTERN).map(tryParseInt); 8 | var key1; 9 | var key2; 10 | var compareFirst = Math.min(keys1.length, keys2.length); 11 | var i, l; 12 | 13 | for (i = 0, l = compareFirst; i < l; i++) { 14 | key1 = keys1[i]; 15 | key2 = keys2[i]; 16 | 17 | if (key1 != key2) { 18 | return key1 > key2 ? 1 : -1; 19 | } 20 | } 21 | 22 | return keys1.length > keys2.length ? 1 : (keys1.length == keys2.length ? 0 : -1); 23 | } 24 | 25 | function tryParseInt(value) { 26 | return ('' + parseInt(value)) == value ? 27 | parseInt(value) : 28 | value; 29 | } 30 | 31 | module.exports = naturalCompare; 32 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/clone.js: -------------------------------------------------------------------------------- 1 | var wrapSingle = require('../wrap-for-optimizing').single; 2 | 3 | var Token = require('../../tokenizer/token'); 4 | 5 | function deep(property) { 6 | var cloned = shallow(property); 7 | for (var i = property.components.length - 1; i >= 0; i--) { 8 | var component = shallow(property.components[i]); 9 | component.value = property.components[i].value.slice(0); 10 | cloned.components.unshift(component); 11 | } 12 | 13 | cloned.dirty = true; 14 | cloned.value = property.value.slice(0); 15 | 16 | return cloned; 17 | } 18 | 19 | function shallow(property) { 20 | var cloned = wrapSingle([ 21 | Token.PROPERTY, 22 | [Token.PROPERTY_NAME, property.name] 23 | ]); 24 | cloned.important = property.important; 25 | cloned.hack = property.hack; 26 | cloned.unused = false; 27 | return cloned; 28 | } 29 | 30 | module.exports = { 31 | deep: deep, 32 | shallow: shallow 33 | }; 34 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/every-values-pair.js: -------------------------------------------------------------------------------- 1 | var Marker = require('../../../tokenizer/marker'); 2 | 3 | function everyValuesPair(fn, left, right) { 4 | var leftSize = left.value.length; 5 | var rightSize = right.value.length; 6 | var total = Math.max(leftSize, rightSize); 7 | var lowerBound = Math.min(leftSize, rightSize) - 1; 8 | var leftValue; 9 | var rightValue; 10 | var position; 11 | 12 | for (position = 0; position < total; position++) { 13 | leftValue = left.value[position] && left.value[position][1] || leftValue; 14 | rightValue = right.value[position] && right.value[position][1] || rightValue; 15 | 16 | if (leftValue == Marker.COMMA || rightValue == Marker.COMMA) { 17 | continue; 18 | } 19 | 20 | if (!fn(leftValue, rightValue, position, position <= lowerBound)) { 21 | return false; 22 | } 23 | } 24 | 25 | return true; 26 | } 27 | 28 | module.exports = everyValuesPair; 29 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/specificities-overlap.js: -------------------------------------------------------------------------------- 1 | var specificity = require('./specificity'); 2 | 3 | function specificitiesOverlap(selector1, selector2, cache) { 4 | var specificity1; 5 | var specificity2; 6 | var i, l; 7 | var j, m; 8 | 9 | for (i = 0, l = selector1.length; i < l; i++) { 10 | specificity1 = findSpecificity(selector1[i][1], cache); 11 | 12 | for (j = 0, m = selector2.length; j < m; j++) { 13 | specificity2 = findSpecificity(selector2[j][1], cache); 14 | 15 | if (specificity1[0] === specificity2[0] && specificity1[1] === specificity2[1] && specificity1[2] === specificity2[2]) { 16 | return true; 17 | } 18 | } 19 | } 20 | 21 | return false; 22 | } 23 | 24 | function findSpecificity(selector, cache) { 25 | var value; 26 | 27 | if (!(selector in cache)) { 28 | cache[selector] = value = specificity(selector); 29 | } 30 | 31 | return value || cache[selector]; 32 | } 33 | 34 | module.exports = specificitiesOverlap; 35 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/extract-import-url-and-media.js: -------------------------------------------------------------------------------- 1 | var split = require('../utils/split'); 2 | 3 | var BRACE_PREFIX = /^\(/; 4 | var BRACE_SUFFIX = /\)$/; 5 | var IMPORT_PREFIX_PATTERN = /^@import/i; 6 | var QUOTE_PREFIX_PATTERN = /['"]\s*/; 7 | var QUOTE_SUFFIX_PATTERN = /\s*['"]/; 8 | var URL_PREFIX_PATTERN = /^url\(\s*/i; 9 | var URL_SUFFIX_PATTERN = /\s*\)/i; 10 | 11 | function extractImportUrlAndMedia(atRuleValue) { 12 | var uri; 13 | var mediaQuery; 14 | var stripped; 15 | var parts; 16 | 17 | stripped = atRuleValue 18 | .replace(IMPORT_PREFIX_PATTERN, '') 19 | .trim() 20 | .replace(URL_PREFIX_PATTERN, '(') 21 | .replace(URL_SUFFIX_PATTERN, ')') 22 | .replace(QUOTE_PREFIX_PATTERN, '') 23 | .replace(QUOTE_SUFFIX_PATTERN, ''); 24 | 25 | parts = split(stripped, ' '); 26 | 27 | uri = parts[0] 28 | .replace(BRACE_PREFIX, '') 29 | .replace(BRACE_SUFFIX, ''); 30 | mediaQuery = parts.slice(1).join(' '); 31 | 32 | return [uri, mediaQuery]; 33 | } 34 | 35 | module.exports = extractImportUrlAndMedia; 36 | -------------------------------------------------------------------------------- /src/tasks/wxml.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var gulp = require('gulp'); 4 | var extToGlob = require('../lib/ext-to-glob'); 5 | var unlink = require('../lib/unlink'); 6 | var compileWxml = require('../compiler/compress-wxml'); 7 | var watchLog = require('../log/watch'); 8 | 9 | var WXML_EXTS = ['wxml', 'html']; 10 | 11 | /** 12 | * @param {object} config 13 | */ 14 | exports.build = function (config) { 15 | return function () { 16 | return compileWxml(config, extToGlob(config, WXML_EXTS)); 17 | }; 18 | } 19 | /** 20 | * @param {object} config 21 | */ 22 | exports.watch = function (config) { 23 | return function (cb) { 24 | var glob = extToGlob(config, WXML_EXTS); 25 | watchLog('wxml', glob) 26 | gulp.watch(glob, { ignored: config.exclude, delay: 1200 }) 27 | .on('change', function (file) { return compileWxml(config, file); }) 28 | .on('add', function (file) { return compileWxml(config, file); }) 29 | .on('unlink', unlink(config.src, config.dist, '.wxml')); 30 | cb && cb(); 31 | 32 | } 33 | } -------------------------------------------------------------------------------- /src/log/color.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | const colors = require('ansi-colors'); 4 | 5 | const availableColors = [ 6 | "cyanBright", 7 | "magentaBright", 8 | "greenBright", 9 | "blueBright", 10 | // "yellowBright", 11 | // "whiteBright", 12 | // "gray", 13 | // "yellow", 14 | "cyan", 15 | "green", 16 | "blue", 17 | // "magenta", // cannot display in power shell 18 | ]; 19 | 20 | const availableStyle = [ 21 | "reset", 22 | // "bold", 23 | "italic", 24 | "dim", 25 | // "underline", 26 | ] 27 | const maps = {} 28 | 29 | let index = 0; 30 | 31 | /** 32 | * 33 | * @param {string} str 34 | * @returns {string} 35 | */ 36 | function color(str) { 37 | str = str && str.trim(); 38 | if (!maps[str]) { 39 | maps[str] = colors.gray.dim.italic.inverse('' + index) + colors 40 | .reset 41 | [availableStyle[index % availableStyle.length]] 42 | [availableColors[index++ % availableColors.length]] 43 | .bold(str); 44 | } 45 | return maps[str]; 46 | } 47 | 48 | module.exports = color; -------------------------------------------------------------------------------- /src/tasks/json.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var gulp = require('gulp'); 4 | var extToGlob = require('../lib/ext-to-glob'); 5 | var unlink = require('../lib/unlink'); 6 | var compileJson = require('../compiler/compile-json'); 7 | var watchLog = require('../log/watch'); 8 | 9 | var JSON_EXTS = ['json', 'jsonc', 'cjson', 'json5']; 10 | 11 | /** 12 | * @param {object} config 13 | */ 14 | exports.build = function (config) { 15 | return function () { 16 | return compileJson(config, extToGlob(config, JSON_EXTS)); 17 | }; 18 | } 19 | /** 20 | * @param {object} config 21 | */ 22 | exports.watch = function (config) { 23 | return function (cb) { 24 | var glob = extToGlob(config, JSON_EXTS); 25 | watchLog('json', glob) 26 | gulp.watch(glob, { ignored: config.exclude }) 27 | .on('change', function (file) { return compileJson(config, file); }) 28 | .on('add', function (file) { return compileJson(config, file); }) 29 | .on('unlink', unlink(config.src, config.dist, '.json')) 30 | ; 31 | cb && cb(); 32 | } 33 | } -------------------------------------------------------------------------------- /src/log/error.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | var colors = require("ansi-colors"); 4 | var log = require("./logger"); 5 | const color = require("./color"); 6 | 7 | /** 8 | * @param {string} TITLE 9 | */ 10 | module.exports = function (TITLE) { 11 | /** 12 | * @param {Error} err 13 | */ 14 | function logError(err) { 15 | const skip = process.env.SKIP_ERROR; 16 | log.error( 17 | color(TITLE), 18 | colors.bold.redBright("[" + colors.symbols.cross + "]"), 19 | colors.red(err.name), 20 | "\n" + 21 | colors.bgRed(err.message), 22 | "\n" + 23 | //@ts-ignore 24 | colors.red.underline(err.fileName || err.relativePath), 25 | "\n" + (skip ? '' : err.stack ? (err.stack + '\n' + err) : JSON.stringify(err, null, 2).substring(0, 2000)) 26 | ); 27 | if (skip) { 28 | if (this && this.emit) { 29 | return this.emit("end", err); 30 | } 31 | } else { 32 | process.exit(1); 33 | } 34 | }; 35 | return logError 36 | }; 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 New Future 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/find-component-in.js: -------------------------------------------------------------------------------- 1 | var compactable = require('../compactable'); 2 | 3 | function findComponentIn(shorthand, longhand) { 4 | var comparator = nameComparator(longhand); 5 | 6 | return findInDirectComponents(shorthand, comparator) || findInSubComponents(shorthand, comparator); 7 | } 8 | 9 | function nameComparator(to) { 10 | return function (property) { 11 | return to.name === property.name; 12 | }; 13 | } 14 | 15 | function findInDirectComponents(shorthand, comparator) { 16 | return shorthand.components.filter(comparator)[0]; 17 | } 18 | 19 | function findInSubComponents(shorthand, comparator) { 20 | var shorthandComponent; 21 | var longhandMatch; 22 | var i, l; 23 | 24 | if (!compactable[shorthand.name].shorthandComponents) { 25 | return; 26 | } 27 | 28 | for (i = 0, l = shorthand.components.length; i < l; i++) { 29 | shorthandComponent = shorthand.components[i]; 30 | longhandMatch = findInDirectComponents(shorthandComponent, comparator); 31 | 32 | if (longhandMatch) { 33 | return longhandMatch; 34 | } 35 | } 36 | 37 | return; 38 | } 39 | 40 | module.exports = findComponentIn; 41 | -------------------------------------------------------------------------------- /src/lib/ext-to-glob.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | 4 | var path = require('path'); 5 | 6 | /** 7 | * 8 | * @param {string} glob 9 | */ 10 | function wrapExclude(glob) { 11 | return glob && /!/.test(glob) ? glob : '!' + glob; 12 | } 13 | /** 14 | * @param {object} config 15 | * @param {string[]|string} exts 16 | * @param {boolean} [includeAssets] 17 | */ 18 | module.exports = function (config, exts, includeAssets) { 19 | var glob = []; 20 | if (typeof exts === 'string') { 21 | glob = [exts]; 22 | } else if (exts.length === 1) { 23 | glob = [config.src + '/**/*.' + exts[0]]; 24 | } else { 25 | glob = [config.src + '/**/*.{' + exts.join(',') + '}']; 26 | } 27 | 28 | if (config.exclude) { 29 | if (config.exclude instanceof Array) { 30 | glob = glob.concat(config.exclude.map(wrapExclude)); 31 | } else { 32 | glob.push(wrapExclude(config.exclude)); 33 | } 34 | } 35 | 36 | if (config.assets) { 37 | var a = path.join(config.src, config.assets).replace(/\\/g, '/') + '/**/*'; 38 | glob.push(includeAssets ? a : '!' + a); 39 | } 40 | return glob.filter(v => v); 41 | } 42 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/remove-duplicates.js: -------------------------------------------------------------------------------- 1 | var Token = require('../../tokenizer/token'); 2 | 3 | var serializeBody = require('../../writer/one-time').body; 4 | var serializeRules = require('../../writer/one-time').rules; 5 | 6 | function removeDuplicates(tokens) { 7 | var matched = {}; 8 | var moreThanOnce = []; 9 | var id, token; 10 | var body, bodies; 11 | 12 | for (var i = 0, l = tokens.length; i < l; i++) { 13 | token = tokens[i]; 14 | if (token[0] != Token.RULE) 15 | continue; 16 | 17 | id = serializeRules(token[1]); 18 | 19 | if (matched[id] && matched[id].length == 1) 20 | moreThanOnce.push(id); 21 | else 22 | matched[id] = matched[id] || []; 23 | 24 | matched[id].push(i); 25 | } 26 | 27 | for (i = 0, l = moreThanOnce.length; i < l; i++) { 28 | id = moreThanOnce[i]; 29 | bodies = []; 30 | 31 | for (var j = matched[id].length - 1; j >= 0; j--) { 32 | token = tokens[matched[id][j]]; 33 | body = serializeBody(token[2]); 34 | 35 | if (bodies.indexOf(body) > -1) 36 | token[2] = []; 37 | else 38 | bodies.push(body); 39 | } 40 | } 41 | } 42 | 43 | module.exports = removeDuplicates; 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | dist/ 64 | 65 | package-lock.json -------------------------------------------------------------------------------- /src/compiler/compile-javascript.js: -------------------------------------------------------------------------------- 1 | 2 | ///@ts-check 3 | 'use strict'; 4 | var gulp = require('gulp'); 5 | var sourcemaps = require('gulp-sourcemaps'); 6 | var empty = require('../lib/empty'); 7 | var replace = require('../lib/multi-replace'); 8 | const pkgVar = require('../lib/package-var'); 9 | const debug = require("../log/compile"); 10 | const size = require('../log/size'); 11 | var error = require("../log/error"); 12 | 13 | var TITLE = 'javascript'; 14 | /** 15 | * 编译TS 16 | * @param {object} config * 17 | * @param {string|string[]} jsFile 18 | */ 19 | function compilejs(config, jsFile) { 20 | return gulp.src(jsFile, { base: config.src, sourcemaps: !config.production, ignore: config.exclude }) 21 | .pipe(debug({ 22 | title: TITLE, 23 | dist: config.dist, 24 | distExt: '.js' 25 | })) 26 | .pipe(config.production ? empty() : sourcemaps.init()) 27 | .pipe(replace(pkgVar(config.var), undefined, "{{", "}}")) 28 | .on('error', error(TITLE)) 29 | .pipe(config.production ? empty() : sourcemaps.write()) 30 | .pipe(gulp.dest(config.dist)) 31 | .pipe(size({ title: TITLE, showFiles: true, showTotal: true })) 32 | 33 | } 34 | module.exports = compilejs -------------------------------------------------------------------------------- /src/compiler/compile-json.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var gulp = require('gulp'); 4 | var rename = require('gulp-rename'); 5 | const debug = require("../log/compile"); 6 | const size = require('../log/size'); 7 | var err = require('../log/error'); 8 | var multiReplace = require('../lib/multi-replace'); 9 | const pkgVar = require('../lib/package-var'); 10 | var jsonMini = require('../lib/json-mini'); 11 | 12 | var TITLE = 'json'; 13 | /** 14 | * 复制 Json文件 15 | * @param {object} config 16 | * @param {string|string[]} [jsonFile] 17 | */ 18 | function replaceJson(config, jsonFile) { 19 | jsonFile = jsonFile || (config.src + '/**/*.{json,jsonc}'); 20 | return gulp 21 | .src(jsonFile, { base: config.src, ignore: config.exclude }) 22 | .pipe(debug({ 23 | title: TITLE, 24 | dist: config.dist, 25 | distExt: '.json' 26 | })) 27 | .pipe(rename({ 'extname': '.json' })) 28 | .pipe(jsonMini(!config.production)) 29 | .on('error', err(TITLE)) 30 | .pipe(multiReplace(pkgVar(config.var), undefined, '{{', '}}')) 31 | .pipe(gulp.dest(config.dist)) 32 | .pipe(size({ title: TITLE, showFiles: true, showTotal: true })) 33 | ; 34 | } 35 | 36 | module.exports = replaceJson; 37 | -------------------------------------------------------------------------------- /src/tasks/image.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var gulp = require('gulp'); 4 | var extToGlob = require('../lib/ext-to-glob'); 5 | var unlink = require('../lib/unlink'); 6 | var compileImage = require('../compiler/compress-image'); 7 | var watchLog = require('../log/watch'); 8 | 9 | var IMAGE_EXTS = ['png', 'jpg', 'jpeg', 'svg', 'gif',]; 10 | 11 | 12 | function compress(config) { 13 | /** 14 | * @param {string|string[]} file 15 | */ 16 | return function (file) { 17 | return compileImage(file, config.dist, { base: config.src, ignore: config.exclude }); 18 | } 19 | } 20 | 21 | /** 22 | * @param {object} config 23 | */ 24 | exports.build = function (config) { 25 | return function () { 26 | return compress(config)(extToGlob(config, IMAGE_EXTS)); 27 | }; 28 | } 29 | 30 | /** 31 | * @param {object} config 32 | */ 33 | exports.watch = function (config) { 34 | return function (cb) { 35 | var glob = extToGlob(config, IMAGE_EXTS); 36 | watchLog('image', glob) 37 | gulp.watch(glob, { ignored: config.exclude, delay: 1200 }) 38 | .on('change', compress(config)) 39 | .on('add', compress(config)) 40 | .on('unlink', unlink(config.src, config.dist)); 41 | cb && cb(); 42 | } 43 | } -------------------------------------------------------------------------------- /src/tasks/javascript.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | var gulp = require("gulp"); 4 | var fs = require("fs"); 5 | var path = require("path"); 6 | var compileJs = require("../compiler/compile-javascript"); 7 | var unlink = require("../lib/unlink"); 8 | var extToGlob = require("../lib/ext-to-glob"); 9 | var watchLog = require("../log/watch"); 10 | 11 | // var JS_EXTS = ["js", "wxs"]; 12 | /** 13 | * @param {object} config 14 | * @param {string[]} JS_EXTS 15 | */ 16 | exports.build = function (config, JS_EXTS) { 17 | return function () { 18 | return compileJs(config, extToGlob(config, JS_EXTS)); 19 | }; 20 | }; 21 | 22 | 23 | /** 24 | * @param {object} config 25 | * @param {string[]} JS_EXTS 26 | */ 27 | exports.watch = function (config, JS_EXTS) { 28 | return function (cb) { 29 | var glob = extToGlob(config, JS_EXTS); 30 | watchLog("javascript-" + JS_EXTS.join('-'), glob); 31 | gulp.watch(glob, { ignored: config.exclude, delay: 1200 }) 32 | .on("change", function (file) { 33 | return compileJs(config, file); 34 | }) 35 | .on("add", function (file) { 36 | return compileJs(config, file); 37 | }) 38 | .on("unlink", unlink(config.src, config.dist, ".js")); 39 | cb && cb(); 40 | }; 41 | }; 42 | -------------------------------------------------------------------------------- /src/tasks/copy.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var gulp = require('gulp'); 4 | var extToGlob = require('../lib/ext-to-glob'); 5 | var unlink = require('../lib/unlink'); 6 | var copy = require('../compiler/copy'); 7 | var watchLog = require('../log/watch'); 8 | 9 | /** 10 | * @param {object} config 11 | */ 12 | function copyTo(config) { 13 | /** 14 | * @param {string|string[]} file 15 | */ 16 | return function (file) { 17 | return copy(config.dist, file, { base: config.src, ignore: config.exclude }); 18 | } 19 | } 20 | 21 | /** 22 | * @param {object} config 23 | */ 24 | exports.build = function (config) { 25 | return function (cb) { 26 | if (config.copy) { 27 | return copyTo(config)(extToGlob(config, config.copy)); 28 | } 29 | cb && cb(); 30 | }; 31 | } 32 | 33 | /** 34 | * @param {object} config 35 | */ 36 | exports.watch = function (config) { 37 | return function (cb) { 38 | if (config.copy) { 39 | watchLog('copy', config.copy); 40 | gulp.watch(extToGlob(config, config.copy), { ignored: config.exclude, delay: 1200 }) 41 | .on('change', copyTo(config)) 42 | .on('add', copyTo(config)) 43 | .on('unlink', unlink(config.src, config.dist)); 44 | } 45 | cb && cb(); 46 | } 47 | } -------------------------------------------------------------------------------- /vendor/clean-css/utils/split.js: -------------------------------------------------------------------------------- 1 | var Marker = require('../tokenizer/marker'); 2 | 3 | function split(value, separator) { 4 | var openLevel = Marker.OPEN_ROUND_BRACKET; 5 | var closeLevel = Marker.CLOSE_ROUND_BRACKET; 6 | var level = 0; 7 | var cursor = 0; 8 | var lastStart = 0; 9 | var lastValue; 10 | var lastCharacter; 11 | var len = value.length; 12 | var parts = []; 13 | 14 | if (value.indexOf(separator) == -1) { 15 | return [value]; 16 | } 17 | 18 | if (value.indexOf(openLevel) == -1) { 19 | return value.split(separator); 20 | } 21 | 22 | while (cursor < len) { 23 | if (value[cursor] == openLevel) { 24 | level++; 25 | } else if (value[cursor] == closeLevel) { 26 | level--; 27 | } 28 | 29 | if (level === 0 && cursor > 0 && cursor + 1 < len && value[cursor] == separator) { 30 | parts.push(value.substring(lastStart, cursor)); 31 | lastStart = cursor + 1; 32 | } 33 | 34 | cursor++; 35 | } 36 | 37 | if (lastStart < cursor + 1) { 38 | lastValue = value.substring(lastStart); 39 | lastCharacter = lastValue[lastValue.length - 1]; 40 | if (lastCharacter == separator) { 41 | lastValue = lastValue.substring(0, lastValue.length - 1); 42 | } 43 | 44 | parts.push(lastValue); 45 | } 46 | 47 | return parts; 48 | } 49 | 50 | module.exports = split; 51 | -------------------------------------------------------------------------------- /vendor/clean-css/writer/one-time.js: -------------------------------------------------------------------------------- 1 | var helpers = require('./helpers'); 2 | 3 | function store(serializeContext, token) { 4 | serializeContext.output.push(typeof token == 'string' ? token : token[1]); 5 | } 6 | 7 | function context() { 8 | var newContext = { 9 | output: [], 10 | store: store 11 | }; 12 | 13 | return newContext; 14 | } 15 | 16 | function all(tokens) { 17 | var oneTimeContext = context(); 18 | helpers.all(oneTimeContext, tokens); 19 | return oneTimeContext.output.join(''); 20 | } 21 | 22 | function body(tokens) { 23 | var oneTimeContext = context(); 24 | helpers.body(oneTimeContext, tokens); 25 | return oneTimeContext.output.join(''); 26 | } 27 | 28 | function property(tokens, position) { 29 | var oneTimeContext = context(); 30 | helpers.property(oneTimeContext, tokens, position, true); 31 | return oneTimeContext.output.join(''); 32 | } 33 | 34 | function rules(tokens) { 35 | var oneTimeContext = context(); 36 | helpers.rules(oneTimeContext, tokens); 37 | return oneTimeContext.output.join(''); 38 | } 39 | 40 | function value(tokens) { 41 | var oneTimeContext = context(); 42 | helpers.value(oneTimeContext, tokens); 43 | return oneTimeContext.output.join(''); 44 | } 45 | 46 | module.exports = { 47 | all: all, 48 | body: body, 49 | property: property, 50 | rules: rules, 51 | value: value 52 | }; 53 | -------------------------------------------------------------------------------- /src/lib/json-mini.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | 4 | var through2 = require('through2'); 5 | var json5 = require('json5'); 6 | 7 | /** 8 | * 9 | * @param {string} json 10 | * @param {boolean} pretty 11 | */ 12 | function mini(json, pretty) { 13 | var data = json5.parse(json); 14 | return JSON.stringify(data, undefined, pretty ? 4 : 0); 15 | } 16 | 17 | /** 18 | * 19 | * @param {boolean} [pretty] - 格式化输出 20 | */ 21 | function jsonMinify(pretty) { 22 | return through2.obj((file, enc, cb) => { 23 | var err = null; 24 | if (file.isNull()) { 25 | return cb(null, file); 26 | } 27 | if (file.isBuffer()) { 28 | try { 29 | file.contents = Buffer.from(mini(file.contents.toString(), pretty)); 30 | } catch (error) { 31 | err = error 32 | err.fileName = file.path; 33 | } 34 | } 35 | if (file.isStream()) { 36 | file.contents = file.contents.pipe(through2.obj((json, enc, cb) => { 37 | try { 38 | cb(null, mini(json.toString(), pretty)); 39 | } catch (error) { 40 | error.fileName = file.path; 41 | cb(error); 42 | } 43 | })); 44 | } 45 | cb(err, file); 46 | }); 47 | } 48 | module.exports = jsonMinify; -------------------------------------------------------------------------------- /src/lib/pretty-time.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | 4 | function getEnvLocale(env = process.env) { 5 | return env.LC_ALL || env.LC_MESSAGES || env.LANG || env.LANGUAGE || ''; 6 | } 7 | 8 | const locale = getEnvLocale().replace(/[.:].*/, ''); 9 | 10 | const units = locale.toLowerCase().startsWith("zh") ? 11 | [ 12 | { name: "纳秒", factor: 1 }, 13 | { name: "微秒", factor: 1e3 }, 14 | { name: "毫秒", factor: 1e6 }, 15 | { name: "秒", factor: 1e9 }, 16 | { name: "分", factor: 6e10 }, 17 | { name: "小时", factor: 36e11 } 18 | ] 19 | : [ 20 | { name: " ns", factor: 1 }, 21 | { name: " us", factor: 1e3 }, 22 | { name: " ms", factor: 1e6 }, 23 | { name: " s", factor: 1e9 }, 24 | { name: " min", factor: 6e10 }, 25 | { name: " hr", factor: 36e11 } 26 | ] 27 | 28 | function prettyTime(time, dec = 2) { 29 | for (let i = 0; i < units.length; i++) { 30 | const { name, factor } = units[i], scaledTime = time / factor; 31 | const maxVal = units[i + 1] && units[i + 1].factor / factor; 32 | const roundedTime = Number((scaledTime).toFixed(dec)); 33 | // if time in cur unit is large enough to be the next unit, continue 34 | if (!maxVal || Math.abs(roundedTime) < maxVal) { 35 | return Number((scaledTime).toFixed(dec)) + name 36 | } 37 | } 38 | } 39 | module.exports = prettyTime; -------------------------------------------------------------------------------- /src/lib/unlink.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | // var del = require('del'); 4 | 5 | // /** 6 | // * @param {string} src 7 | // * @param {string} dist 8 | // * @param {string} [suffix] 9 | // */ 10 | // module.exports = function (src,dist,suffix) { 11 | // /** 12 | // * @param {string} file 13 | // */ 14 | // return function(file){ 15 | // // log(colors.red('delete'), distFile); 16 | // var distFile = file.replace(src, dist) 17 | // if(suffix){ 18 | // distFile = distFile.replace(/\.\w*$/, suffix); 19 | // } 20 | // return del(distFile); 21 | // }; 22 | // } 23 | 24 | const rm = require('rimraf'); 25 | const colors = require('ansi-colors'); 26 | // var path = require('path'); 27 | const log = require('../log/logger') 28 | module.exports = function (src, dist, suffix) { 29 | /** 30 | * @param {string} file 31 | */ 32 | return function (file) { 33 | var distFile = file.replace(src, dist) 34 | if (suffix) { 35 | distFile = distFile.replace(/\.\w*$/, suffix); 36 | } 37 | // return del(distFile); 38 | rm(distFile, {maxBusyTries: 5,}, function(err){ 39 | if(!err){ 40 | log(colors.red.dim('deleted:'), distFile); 41 | }else{ 42 | log.error(colors.redBright('fail to delete'), distFile,err); 43 | } 44 | }) 45 | }; 46 | } -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/populate-components.js: -------------------------------------------------------------------------------- 1 | var compactable = require('../compactable'); 2 | var InvalidPropertyError = require('../invalid-property-error'); 3 | 4 | function populateComponents(properties, validator, warnings) { 5 | var component; 6 | var j, m; 7 | 8 | for (var i = properties.length - 1; i >= 0; i--) { 9 | var property = properties[i]; 10 | var descriptor = compactable[property.name]; 11 | 12 | if (descriptor && descriptor.shorthand) { 13 | property.shorthand = true; 14 | property.dirty = true; 15 | 16 | try { 17 | property.components = descriptor.breakUp(property, compactable, validator); 18 | 19 | if (descriptor.shorthandComponents) { 20 | for (j = 0, m = property.components.length; j < m; j++) { 21 | component = property.components[j]; 22 | component.components = compactable[component.name].breakUp(component, compactable, validator); 23 | } 24 | } 25 | } catch (e) { 26 | if (e instanceof InvalidPropertyError) { 27 | property.components = []; // this will set property.unused to true below 28 | warnings.push(e.message); 29 | } else { 30 | throw e; 31 | } 32 | } 33 | 34 | if (property.components.length > 0) 35 | property.multiplex = property.components[0].multiplex; 36 | else 37 | property.unused = true; 38 | } 39 | } 40 | } 41 | 42 | module.exports = populateComponents; 43 | -------------------------------------------------------------------------------- /vendor/clean-css/writer/simple.js: -------------------------------------------------------------------------------- 1 | var all = require('./helpers').all; 2 | 3 | function store(serializeContext, token) { 4 | var value = typeof token == 'string' ? 5 | token : 6 | token[1]; 7 | var wrap = serializeContext.wrap; 8 | 9 | wrap(serializeContext, value); 10 | track(serializeContext, value); 11 | serializeContext.output.push(value); 12 | } 13 | 14 | function wrap(serializeContext, value) { 15 | if (serializeContext.column + value.length > serializeContext.format.wrapAt) { 16 | track(serializeContext, serializeContext.format.breakWith); 17 | serializeContext.output.push(serializeContext.format.breakWith); 18 | } 19 | } 20 | 21 | function track(serializeContext, value) { 22 | var parts = value.split('\n'); 23 | 24 | serializeContext.line += parts.length - 1; 25 | serializeContext.column = parts.length > 1 ? 0 : (serializeContext.column + parts.pop().length); 26 | } 27 | 28 | function serializeStyles(tokens, context) { 29 | var serializeContext = { 30 | column: 0, 31 | format: context.options.format, 32 | indentBy: 0, 33 | indentWith: '', 34 | line: 1, 35 | output: [], 36 | spaceAfterClosingBrace: context.options.compatibility.properties.spaceAfterClosingBrace, 37 | store: store, 38 | wrap: context.options.format.wrapAt ? 39 | wrap : 40 | function () { /* noop */ } 41 | }; 42 | 43 | all(serializeContext, tokens); 44 | 45 | return { 46 | styles: serializeContext.output.join('') 47 | }; 48 | } 49 | 50 | module.exports = serializeStyles; 51 | -------------------------------------------------------------------------------- /src/log/warn.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | const colors = require("ansi-colors"); 4 | const color = require("./color"); 5 | const log = require("./logger"); 6 | 7 | /** 8 | * @param {string} TITLE 9 | * @param {string} [sub] 10 | */ 11 | module.exports = function(TITLE, sub) { 12 | TITLE = color(TITLE); 13 | if (sub) { 14 | TITLE += " " + colors.whiteBright(`<${colors.bold.underline(sub)}>`); 15 | } 16 | /** 17 | * @param {any} info 18 | */ 19 | function logError(info) { 20 | const skip = process.env.NO_WARN; 21 | if (!skip) { 22 | if (typeof info === "string" || !info) { 23 | log.warn(TITLE, info || ""); 24 | } else { 25 | log.warn(TITLE, colors.yellowBright(info.message || ""), colors.gray.bgYellowBright.bold(info.code || "")); 26 | 27 | if (info.loc) { 28 | log.warn( 29 | colors.gray("↓"), 30 | colors.bgYellow.gray("warning"), 31 | "@line", 32 | colors.yellowBright(info.loc.line), 33 | "col", 34 | colors.yellowBright(info.loc.column), 35 | "in", 36 | colors.blue.underline(info.loc.file || ""), 37 | colors.gray("↓\n") + info.frame, 38 | ); 39 | } 40 | if (info.url) { 41 | log.warn("see →", colors.blue.underline(info.url), "for warning detail."); 42 | } 43 | } 44 | } 45 | } 46 | return logError; 47 | }; 48 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/input-source-map-tracker.js: -------------------------------------------------------------------------------- 1 | var SourceMapConsumer = require('source-map').SourceMapConsumer; 2 | 3 | function inputSourceMapTracker() { 4 | var maps = {}; 5 | 6 | return { 7 | all: all.bind(null, maps), 8 | isTracking: isTracking.bind(null, maps), 9 | originalPositionFor: originalPositionFor.bind(null, maps), 10 | track: track.bind(null, maps) 11 | }; 12 | } 13 | 14 | function all(maps) { 15 | return maps; 16 | } 17 | 18 | function isTracking(maps, source) { 19 | return source in maps; 20 | } 21 | 22 | function originalPositionFor(maps, metadata, range, selectorFallbacks) { 23 | var line = metadata[0]; 24 | var column = metadata[1]; 25 | var source = metadata[2]; 26 | var position = { 27 | line: line, 28 | column: column + range 29 | }; 30 | var originalPosition; 31 | 32 | while (!originalPosition && position.column > column) { 33 | position.column--; 34 | originalPosition = maps[source].originalPositionFor(position); 35 | } 36 | 37 | if (!originalPosition || originalPosition.column < 0) { 38 | return metadata; 39 | } 40 | 41 | if (originalPosition.line === null && line > 1 && selectorFallbacks > 0) { 42 | return originalPositionFor(maps, [line - 1, column, source], range, selectorFallbacks - 1); 43 | } 44 | 45 | return originalPosition.line !== null ? 46 | toMetadata(originalPosition) : 47 | metadata; 48 | } 49 | 50 | function toMetadata(asHash) { 51 | return [asHash.line, asHash.column, asHash.source]; 52 | } 53 | 54 | function track(maps, source, data) { 55 | maps[source] = new SourceMapConsumer(data); 56 | } 57 | 58 | module.exports = inputSourceMapTracker; 59 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/properties/optimize.js: -------------------------------------------------------------------------------- 1 | var mergeIntoShorthands = require('./merge-into-shorthands'); 2 | var overrideProperties = require('./override-properties'); 3 | var populateComponents = require('./populate-components'); 4 | 5 | var restoreWithComponents = require('../restore-with-components'); 6 | 7 | var wrapForOptimizing = require('../../wrap-for-optimizing').all; 8 | var removeUnused = require('../../remove-unused'); 9 | var restoreFromOptimizing = require('../../restore-from-optimizing'); 10 | 11 | var OptimizationLevel = require('../../../options/optimization-level').OptimizationLevel; 12 | 13 | function optimizeProperties(properties, withOverriding, withMerging, context) { 14 | var levelOptions = context.options.level[OptimizationLevel.Two]; 15 | var _properties = wrapForOptimizing(properties, false, levelOptions.skipProperties); 16 | var _property; 17 | var i, l; 18 | 19 | populateComponents(_properties, context.validator, context.warnings); 20 | 21 | for (i = 0, l = _properties.length; i < l; i++) { 22 | _property = _properties[i]; 23 | if (_property.block) { 24 | optimizeProperties(_property.value[0][1], withOverriding, withMerging, context); 25 | } 26 | } 27 | 28 | if (withMerging && levelOptions.mergeIntoShorthands) { 29 | mergeIntoShorthands(_properties, context.validator); 30 | } 31 | 32 | if (withOverriding && levelOptions.overrideProperties) { 33 | overrideProperties(_properties, withMerging, context.options.compatibility, context.validator); 34 | } 35 | 36 | restoreFromOptimizing(_properties, restoreWithComponents); 37 | removeUnused(_properties); 38 | } 39 | 40 | module.exports = optimizeProperties; 41 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-1/shorten-hsl.js: -------------------------------------------------------------------------------- 1 | // HSL to RGB converter. Both methods adapted from: 2 | // http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript 3 | 4 | function hslToRgb(h, s, l) { 5 | var r, g, b; 6 | 7 | // normalize hue orientation b/w 0 and 360 degrees 8 | h = h % 360; 9 | if (h < 0) 10 | h += 360; 11 | h = ~~h / 360; 12 | 13 | if (s < 0) 14 | s = 0; 15 | else if (s > 100) 16 | s = 100; 17 | s = ~~s / 100; 18 | 19 | if (l < 0) 20 | l = 0; 21 | else if (l > 100) 22 | l = 100; 23 | l = ~~l / 100; 24 | 25 | if (s === 0) { 26 | r = g = b = l; // achromatic 27 | } else { 28 | var q = l < 0.5 ? 29 | l * (1 + s) : 30 | l + s - l * s; 31 | var p = 2 * l - q; 32 | r = hueToRgb(p, q, h + 1/3); 33 | g = hueToRgb(p, q, h); 34 | b = hueToRgb(p, q, h - 1/3); 35 | } 36 | 37 | return [~~(r * 255), ~~(g * 255), ~~(b * 255)]; 38 | } 39 | 40 | function hueToRgb(p, q, t) { 41 | if (t < 0) t += 1; 42 | if (t > 1) t -= 1; 43 | if (t < 1/6) return p + (q - p) * 6 * t; 44 | if (t < 1/2) return q; 45 | if (t < 2/3) return p + (q - p) * (2/3 - t) * 6; 46 | return p; 47 | } 48 | 49 | function shortenHsl(hue, saturation, lightness) { 50 | var asRgb = hslToRgb(hue, saturation, lightness); 51 | var redAsHex = asRgb[0].toString(16); 52 | var greenAsHex = asRgb[1].toString(16); 53 | var blueAsHex = asRgb[2].toString(16); 54 | 55 | return '#' + 56 | ((redAsHex.length == 1 ? '0' : '') + redAsHex) + 57 | ((greenAsHex.length == 1 ? '0' : '') + greenAsHex) + 58 | ((blueAsHex.length == 1 ? '0' : '') + blueAsHex); 59 | } 60 | 61 | module.exports = shortenHsl; 62 | -------------------------------------------------------------------------------- /src/log/logger.js: -------------------------------------------------------------------------------- 1 | 2 | ///@ts-check 3 | "use strict"; 4 | 5 | const colors = require("ansi-colors"); 6 | 7 | const noColor = process.argv.indexOf('--no-color') > 0; 8 | 9 | // function addColor(str) { 10 | // if (process.argv.indexOf('--no-color') > 0) { 11 | // return str; 12 | // } 13 | 14 | // return colors.gray(str); 15 | // } 16 | 17 | function getTime(level) { 18 | const time = new Date().toLocaleTimeString('en-US', { hour12: false }); 19 | if (noColor) { 20 | return '[' + time + ']'; 21 | } else { 22 | switch (level) { 23 | case 1: 24 | return colors.yellowBright('[') + colors.gray(time) + colors.yellowBright(']'); 25 | case 2: 26 | return colors.red('[') + colors.gray(time) + colors.red(']'); 27 | case -1: 28 | return colors.gray('[') + colors.gray(time) + colors.gray(']'); 29 | default: 30 | return '[' + colors.gray(time) + ']'; 31 | } 32 | 33 | } 34 | } 35 | 36 | 37 | function log() { 38 | console.log.apply(console, Array.prototype.concat.apply([getTime()], arguments)); 39 | return this; 40 | } 41 | 42 | function info() { 43 | console.info.apply(console, Array.prototype.concat.apply([getTime(-1)], arguments)); 44 | return this; 45 | } 46 | 47 | function warn() { 48 | console.warn.apply(console, Array.prototype.concat.apply([getTime(1)], arguments)); 49 | return this; 50 | } 51 | 52 | function error() { 53 | console.error.apply(console, Array.prototype.concat.apply([getTime(2)], arguments)); 54 | return this; 55 | } 56 | 57 | module.exports = log; 58 | module.exports.info = info; 59 | module.exports.warn = warn; 60 | module.exports.error = error; -------------------------------------------------------------------------------- /src/tasks/wxss.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var path = require('path'); 4 | var gulp = require('gulp'); 5 | 6 | var extToSrc = require('../lib/ext-to-glob'); 7 | var unlink = require('../lib/unlink'); 8 | var compileWxss = require('../compiler/compile-wxss'); 9 | var watchLog = require('../log/watch'); 10 | 11 | var WXSS_EXTS = ['scss', 'sass', 'css', 'wxss']; 12 | 13 | /** 14 | * @param {object} config 15 | */ 16 | function compile(config) { 17 | return compileWxss(config, extToSrc(config, WXSS_EXTS)); 18 | } 19 | 20 | /** 21 | * @param {object} config 22 | */ 23 | exports.build = function (config) { 24 | return function () { 25 | return compile(config); 26 | }; 27 | } 28 | 29 | function isAsset(file, config) { 30 | return config.assets && file.startsWith(path.join(config.src, config.assets)); 31 | } 32 | 33 | /** 34 | * @param {object} config 35 | */ 36 | exports.watch = function (config) { 37 | var update = function (file) { 38 | // console.warn(file,JSON.stringify(arguments)) 39 | if (isAsset(file, config)) { 40 | return compile(config);//依赖资源文件更改全部编译 41 | } else { 42 | return compileWxss(config, file); 43 | } 44 | }; 45 | 46 | return function (cb) { 47 | var glob = extToSrc(config, WXSS_EXTS, true); 48 | watchLog('wxss', glob) 49 | gulp.watch(glob, { ignored: config.exclude, delay: 1800 }) 50 | .on('change', update) 51 | .on('add', update) 52 | .on('unlink', function (file) { 53 | if (isAsset(file, config)) { 54 | return compile(config); 55 | } else { 56 | return unlink(config.src, config.dist, '.wxss')(file); 57 | } 58 | }); 59 | cb && cb(); 60 | } 61 | } -------------------------------------------------------------------------------- /src/lib/rollup-plugins.js: -------------------------------------------------------------------------------- 1 | 2 | ///@ts-check 3 | "use strict"; 4 | const warn = require("../log/warn"); 5 | 6 | const TITLE = 'rollup-plugin'; 7 | let PLUGINS = undefined; 8 | /** 9 | * 加载插件 10 | * @param {string} [name] 11 | * @returns {any[]} 12 | */ 13 | module.exports = function loadPlugins(name) { 14 | if (PLUGINS) { 15 | return PLUGINS; 16 | } else { 17 | PLUGINS = []; 18 | } 19 | try { 20 | const json = require("@rollup/plugin-json"); 21 | PLUGINS.push(json()); 22 | } catch (error) { 23 | warn(TITLE, name)(error); 24 | } 25 | try { 26 | const replace = require("@rollup/plugin-replace"); 27 | // @ts-ignore 28 | PLUGINS.push(replace({ 29 | 'process.env.NODE_ENV': JSON.stringify( 30 | process.env.NODE_ENV || 'development', 31 | ) 32 | })); 33 | } catch (error) { 34 | try { 35 | const replace = require("@rollup/plugin-replace"); 36 | // @ts-ignore 37 | PLUGINS.push(replace({ 38 | 'process.env.NODE_ENV': JSON.stringify( 39 | process.env.NODE_ENV || 'development', 40 | ) 41 | })); 42 | } catch (error) { 43 | warn(TITLE, name)(error); 44 | } 45 | } 46 | try { 47 | const rollupNodeResolve = require("@rollup/plugin-node-resolve"); 48 | PLUGINS.push( 49 | //@ts-ignore 50 | rollupNodeResolve.nodeResolve ({ 51 | // modulesOnly: true, 52 | }), 53 | ); 54 | } catch (error) { 55 | warn(TITLE, name)(error); 56 | } 57 | try { 58 | const rollupCommonjs = require("@rollup/plugin-commonjs"); 59 | PLUGINS.push( 60 | //@ts-ignore 61 | rollupCommonjs({}), 62 | ); 63 | } catch (error) { 64 | warn(TITLE, name)(error); 65 | } 66 | 67 | return PLUGINS; 68 | } 69 | -------------------------------------------------------------------------------- /src/tasks/typescript.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | var gulp = require("gulp"); 4 | var fs = require("fs"); 5 | 6 | var colors = require('ansi-colors'); 7 | const color = require('../log/color'); 8 | var compileTs = require("../compiler/compile-typescript"); 9 | var unlink = require("../lib/unlink"); 10 | var extToGlob = require("../lib/ext-to-glob"); 11 | var watchLog = require("../log/watch"); 12 | var log = require('../log/logger'); 13 | 14 | var TS_EXTS = ["ts"]; 15 | /** 16 | * @param {object} config 17 | */ 18 | exports.build = function (config) { 19 | if (config.tsconfig || fs.existsSync("tsconfig.json")) { 20 | return function () { 21 | config.tsconfig = config.tsconfig || "tsconfig.json"; 22 | return compileTs(config); 23 | } 24 | } else { 25 | log.info( 26 | color('typescript:'), 27 | colors.gray('`tsconfig.json` was not found. Skip typescript compilation!') 28 | ); 29 | return function (cb) { 30 | cb && cb(); 31 | } 32 | } 33 | }; 34 | 35 | exports.pushArrayOrItem = function pushArrayOrItem(arr, item) { 36 | if (arr instanceof Array) { 37 | return arr.slice(0).push(item) 38 | } else { 39 | return arr ? [arr, item] : [item] 40 | } 41 | } 42 | /** 43 | * @param {object} config 44 | */ 45 | exports.watch = function (config) { 46 | return function (cb) { 47 | var glob = extToGlob(config, TS_EXTS); 48 | watchLog("typescript", glob); 49 | gulp.watch(glob, { 50 | ignored: exports.pushArrayOrItem(config.exclude, config.src + "/*/**.d.ts"), 51 | delay: 1200 52 | }) 53 | 54 | .on("change", function (file) { 55 | return compileTs(config, file); 56 | }) 57 | .on("add", function (file) { 58 | return compileTs(config, file); 59 | }) 60 | .on("unlink", unlink(config.src, config.dist, ".js")); 61 | cb && cb(); 62 | }; 63 | }; 64 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/restore-from-optimizing.js: -------------------------------------------------------------------------------- 1 | var Hack = require('./hack'); 2 | 3 | var Marker = require('../tokenizer/marker'); 4 | 5 | var ASTERISK_HACK = '*'; 6 | var BACKSLASH_HACK = '\\'; 7 | var IMPORTANT_TOKEN = '!important'; 8 | var UNDERSCORE_HACK = '_'; 9 | var BANG_HACK = '!ie'; 10 | 11 | function restoreFromOptimizing(properties, restoreCallback) { 12 | var property; 13 | var restored; 14 | var current; 15 | var i; 16 | 17 | for (i = properties.length - 1; i >= 0; i--) { 18 | property = properties[i]; 19 | 20 | if (property.unused) { 21 | continue; 22 | } 23 | 24 | if (!property.dirty && !property.important && !property.hack) { 25 | continue; 26 | } 27 | 28 | if (restoreCallback) { 29 | restored = restoreCallback(property); 30 | property.value = restored; 31 | } else { 32 | restored = property.value; 33 | } 34 | 35 | if (property.important) { 36 | restoreImportant(property); 37 | } 38 | 39 | if (property.hack) { 40 | restoreHack(property); 41 | } 42 | 43 | if ('all' in property) { 44 | current = property.all[property.position]; 45 | current[1][1] = property.name; 46 | 47 | current.splice(2, current.length - 1); 48 | Array.prototype.push.apply(current, restored); 49 | } 50 | } 51 | } 52 | 53 | function restoreImportant(property) { 54 | property.value[property.value.length - 1][1] += IMPORTANT_TOKEN; 55 | } 56 | 57 | function restoreHack(property) { 58 | if (property.hack[0] == Hack.UNDERSCORE) { 59 | property.name = UNDERSCORE_HACK + property.name; 60 | } else if (property.hack[0] == Hack.ASTERISK) { 61 | property.name = ASTERISK_HACK + property.name; 62 | } else if (property.hack[0] == Hack.BACKSLASH) { 63 | property.value[property.value.length - 1][1] += BACKSLASH_HACK + property.hack[1]; 64 | } else if (property.hack[0] == Hack.BANG) { 65 | property.value[property.value.length - 1][1] += Marker.SPACE + BANG_HACK; 66 | } 67 | } 68 | 69 | module.exports = restoreFromOptimizing; 70 | -------------------------------------------------------------------------------- /.github/workflows/npmpublish.yml: -------------------------------------------------------------------------------- 1 | name: ReleaseNPM 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | - "V*" 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v1 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: 12 17 | - run: npm i 18 | - run: npm test 19 | 20 | publish-npm: 21 | needs: build 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v1 25 | - name: publish to npm 26 | uses: actions/setup-node@v1 27 | with: 28 | node-version: 12 29 | registry-url: https://registry.npmjs.org/ 30 | - run: npm publish 31 | env: 32 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 33 | 34 | publish-gpr: 35 | needs: build 36 | runs-on: ubuntu-latest 37 | steps: 38 | - uses: actions/checkout@v1 39 | - name: publish to github registry 40 | uses: actions/setup-node@v1 41 | with: 42 | node-version: 12 43 | registry-url: "https://npm.pkg.github.com" 44 | scope: "@newfuture" 45 | - run: | 46 | sed -i '0,/miniprogram-build/s/miniprogram-build/@newfuture\/&/' package.json 47 | npm publish --access public 48 | env: 49 | NPM_REGISTRY_URL: https://npm.pkg.github.com/ 50 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} 51 | 52 | github-release: 53 | needs: build 54 | runs-on: ubuntu-latest 55 | steps: 56 | - uses: actions/checkout@v1 57 | - name: Create github Release 58 | uses: Roang-zero1/github-create-release-action@v1.0.2 59 | env: 60 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 61 | UPDATE_EXISTING: true 62 | -------------------------------------------------------------------------------- /src/lib/clean-css.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | const path = require('path'); 4 | const through = require('through2'); 5 | 6 | // const applySourceMap = require('vinyl-sourcemaps-apply'); 7 | const CleanCSS = require('../../vendor/clean-css/clean'); 8 | const PluginError = require('./error'); 9 | 10 | module.exports = (options, callback) => { 11 | 12 | let _callback = callback || (o => undefined); 13 | 14 | return through.obj(function (file, enc, cb) { 15 | 16 | let _options = Object.assign({}, options || {}); 17 | 18 | if (file.isNull()) { 19 | return cb(null, file); 20 | } 21 | if (file.isStream()) { 22 | this.emit('error', new PluginError('gulp-clean-css', 'Streaming not supported!')); 23 | return cb(null, file); 24 | } 25 | 26 | if (file.sourceMap) { 27 | _options.sourceMap = JSON.parse(JSON.stringify(file.sourceMap)); 28 | } 29 | 30 | const content = { 31 | [file.path]: {styles: file.contents ? file.contents.toString() : ''} 32 | }; 33 | if (!_options.rebaseTo && _options.rebase !== false) { 34 | _options.rebaseTo = path.dirname(file.path); 35 | } 36 | 37 | // @ts-ignore 38 | new CleanCSS(_options).minify(content, (errors, css) => { 39 | 40 | if (errors) { 41 | return cb(errors.join(' ')); 42 | } 43 | 44 | let details = { 45 | 'stats': css.stats, 46 | 'errors': css.errors, 47 | 'warnings': css.warnings, 48 | 'path': file.path, 49 | 'name': file.path.split(file.base)[1] 50 | }; 51 | 52 | if (css.sourceMap) { 53 | details['sourceMap'] = css.sourceMap; 54 | } 55 | _callback(details); 56 | 57 | file.contents = Buffer.from(css.styles); 58 | 59 | if (css.sourceMap) { 60 | const iMap = JSON.parse(css.sourceMap); 61 | const oMap = Object.assign({}, iMap, { 62 | file: path.relative(file.base, file.path), 63 | sources: iMap.sources.map(mapSrc => path.relative(file.base, mapSrc)) 64 | }); 65 | // applySourceMap(file, oMap); 66 | } 67 | cb(null, file); 68 | }); 69 | }); 70 | }; 71 | -------------------------------------------------------------------------------- /src/tasks/wxts.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | var gulp = require("gulp"); 4 | var fs = require("fs"); 5 | 6 | var colors = require('ansi-colors'); 7 | var json5 = require('json5'); 8 | 9 | var log = require('../log/logger'); 10 | const color = require('../log/color'); 11 | 12 | var compileWxts = require("../compiler/compile-wxts"); 13 | var unlink = require("../lib/unlink"); 14 | var extToGlob = require("../lib/ext-to-glob"); 15 | var watchLog = require("../log/watch"); 16 | 17 | const ts = require('./typescript'); 18 | var WXTS_EXTS = ["wxts"]; 19 | function compile(config, file) { 20 | var tsconfig = {}; 21 | if (config.tsconfig) { 22 | var buff = fs.readFileSync(config.tsconfig); 23 | tsconfig = json5.parse(buff.toString()); 24 | } 25 | return compileWxts(config, file, tsconfig); 26 | } 27 | /** 28 | * @param {object} config 29 | */ 30 | exports.build = function (config) { 31 | if (config.tsconfig || fs.existsSync("tsconfig.json")) { 32 | return function () { 33 | config.tsconfig = config.tsconfig || "tsconfig.json"; 34 | return compile(config, extToGlob(config, WXTS_EXTS)) 35 | } 36 | } else { 37 | log.info( 38 | color('wxts:'), 39 | colors.gray('`tsconfig.json` was not found. Skip WXTS(WeiXin TypesSript) compilation!') 40 | ); 41 | return function (cb) { 42 | cb && cb(); 43 | } 44 | } 45 | }; 46 | 47 | /** 48 | * @param {object} config 49 | */ 50 | exports.watch = function (config) { 51 | return function (cb) { 52 | var glob = extToGlob(config, WXTS_EXTS); 53 | watchLog("wxts", glob); 54 | gulp.watch(glob, { 55 | ignored: ts.pushArrayOrItem(config.exclude, config.src + "/*/**.d.ts"), 56 | delay: 1200 57 | }) 58 | .on("change", function (file) { 59 | return compile(config, file); 60 | }) 61 | .on("add", function (file) { 62 | return compile(config, file); 63 | }) 64 | .on("unlink", unlink(config.src, config.dist, ".wxs")); 65 | cb && cb(); 66 | }; 67 | }; 68 | -------------------------------------------------------------------------------- /src/compiler/compress-wxml.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | var gulp = require("gulp"); 4 | // var htmlmin = require("gulp-htmlmin"); 5 | var rename = require("gulp-rename"); 6 | // const debug = require("../log/compile"); 7 | const size = require("../log/size"); 8 | var err = require("../log/error"); 9 | // var minimize = require("gulp-minimize"); 10 | 11 | var TITLE = "wxml"; 12 | /** 13 | * 14 | * @param {object} config 15 | * @param {string|string[]} wxmlsrc 16 | */ 17 | function compress(config, wxmlsrc) { 18 | return ( 19 | gulp 20 | .src(wxmlsrc, { base: config.src, ignore: config.exclude }) 21 | // .pipe(debug({ 22 | // title: TITLE, 23 | // // dist: config.dist, 24 | // distExt: '.wxml' 25 | // })) 26 | // .pipe( 27 | // // minimize({ 28 | // // // spare: true 29 | // // quotes: true, 30 | // // dom: { 31 | // // xmlMode: true, 32 | // // recognizeSelfClosing: true, 33 | // // }, 34 | // // }), 35 | // htmlmin({ 36 | // caseSensitive: true, 37 | // collapseWhitespace: true, 38 | // collapseBooleanAttributes: false, 39 | // removeComments: config.production, 40 | // // minifyCSS: true, 41 | // keepClosingSlash: true, 42 | // html5: true, 43 | // // sortClassName: true, 44 | // // includeAutoGeneratedTags: true, 45 | // // ignoreCustomFragments: [/\{{2,}[\s\S]*?\}{2,}/], 46 | // // trimCustomFragments: false 47 | // customEventAttributes: [/^bind:?[a-z]+/, /^catch:?[a-z]+/, /^wx:[a-z]+/], 48 | // }) 49 | // ) 50 | .on("error", err(TITLE)) 51 | .pipe(rename({ extname: ".wxml" })) 52 | .pipe(gulp.dest(config.dist)) 53 | .pipe(size({ title: TITLE, showFiles: true })) 54 | ); 55 | } 56 | 57 | module.exports = compress; 58 | -------------------------------------------------------------------------------- /src/compiler/compile-typescript.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | var gulp = require("gulp"); 4 | var sourcemaps = require("gulp-sourcemaps"); 5 | const debug = require("../log/compile"); 6 | const size = require('../log/size'); 7 | // var empty = require("../lib/empty"); 8 | const pkgVar = require('../lib/package-var'); 9 | var replace = require("../lib/multi-replace"); 10 | // var tsImport = require("../lib/tsimport"); 11 | var error = require("../log/error"); 12 | 13 | var TITLE = "typescript"; 14 | /** 15 | * 编译TS 16 | * @param {object} config * 17 | * @param {string|string[]} [tsFile] 18 | */ 19 | function compileTS(config, tsFile) { 20 | var ts = require("gulp-typescript"); 21 | // var resolver = require("@taqtile/gulp-module-resolver"); 22 | var tsProject = ts.createProject(config.tsconfig, { 23 | // getCustomTransformers: (program) => ({ 24 | // before: [require("ts-transform-paths").default()] 25 | // }) 26 | getCustomTransformers: (program) => require("ts-transform-paths").default() 27 | }); 28 | 29 | var src = tsFile ? gulp.src(tsFile, { base: config.src, sourcemaps: true, ignore: config.exclude }) : tsProject.src(); 30 | // console.log(tsFile,src) 31 | return src 32 | .on("error", error(TITLE)) 33 | .pipe(debug({ 34 | title: TITLE, 35 | dist: config.dist, 36 | distExt: '.js' 37 | })) 38 | .pipe(sourcemaps.init()) 39 | .pipe(replace(pkgVar(config.var), undefined, "{{", "}}")) 40 | .pipe(tsProject(ts.reporter.fullReporter(true))) 41 | .on("error", error(TITLE)) 42 | .js 43 | // .pipe(require('gulp-ts-path-alias')(tsProject.config.compilerOptions.baseUrl,tsProject.config.compilerOptions.paths)) 44 | // .pipe(tsProject.options.baseUrl && tsProject.options.paths ? tsImport(tsProject.config.compilerOptions) : empty()) 45 | // .pipe(tsProject.options.baseUrl && tsProject.options.paths ? resolver(tsProject.config.compilerOptions.outDir) : empty()) 46 | .pipe(sourcemaps.write('./')) 47 | .pipe(gulp.dest(config.dist)) 48 | .pipe(size({ title: TITLE, showFiles: true })); 49 | } 50 | module.exports = compileTS; 51 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/load-remote-resource.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var https = require('https'); 3 | var url = require('url'); 4 | 5 | var isHttpResource = require('../utils/is-http-resource'); 6 | var isHttpsResource = require('../utils/is-https-resource'); 7 | var override = require('../utils/override'); 8 | 9 | var HTTP_PROTOCOL = 'http:'; 10 | 11 | function loadRemoteResource(uri, inlineRequest, inlineTimeout, callback) { 12 | var proxyProtocol = inlineRequest.protocol || inlineRequest.hostname; 13 | var errorHandled = false; 14 | var requestOptions; 15 | var fetch; 16 | 17 | requestOptions = override( 18 | url.parse(uri), 19 | inlineRequest || {} 20 | ); 21 | 22 | if (inlineRequest.hostname !== undefined) { 23 | // overwrite as we always expect a http proxy currently 24 | requestOptions.protocol = inlineRequest.protocol || HTTP_PROTOCOL; 25 | requestOptions.path = requestOptions.href; 26 | } 27 | 28 | fetch = (proxyProtocol && !isHttpsResource(proxyProtocol)) || isHttpResource(uri) ? 29 | http.get : 30 | https.get; 31 | 32 | fetch(requestOptions, function (res) { 33 | var chunks = []; 34 | var movedUri; 35 | 36 | if (errorHandled) { 37 | return; 38 | } 39 | 40 | if (res.statusCode < 200 || res.statusCode > 399) { 41 | return callback(res.statusCode, null); 42 | } else if (res.statusCode > 299) { 43 | movedUri = url.resolve(uri, res.headers.location); 44 | return loadRemoteResource(movedUri, inlineRequest, inlineTimeout, callback); 45 | } 46 | 47 | res.on('data', function (chunk) { 48 | chunks.push(chunk.toString()); 49 | }); 50 | res.on('end', function () { 51 | var body = chunks.join(''); 52 | callback(null, body); 53 | }); 54 | }) 55 | .on('error', function (res) { 56 | if (errorHandled) { 57 | return; 58 | } 59 | 60 | errorHandled = true; 61 | callback(res.message, null); 62 | }) 63 | .on('timeout', function () { 64 | if (errorHandled) { 65 | return; 66 | } 67 | 68 | errorHandled = true; 69 | callback('timeout', null); 70 | }) 71 | .setTimeout(inlineTimeout); 72 | } 73 | 74 | module.exports = loadRemoteResource; 75 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/extract-properties.js: -------------------------------------------------------------------------------- 1 | // This extractor is used in level 2 optimizations 2 | // IMPORTANT: Mind Token class and this code is not related! 3 | // Properties will be tokenized in one step, see #429 4 | 5 | var Token = require('../../tokenizer/token'); 6 | var serializeRules = require('../../writer/one-time').rules; 7 | var serializeValue = require('../../writer/one-time').value; 8 | 9 | function extractProperties(token) { 10 | var properties = []; 11 | var inSpecificSelector; 12 | var property; 13 | var name; 14 | var value; 15 | var i, l; 16 | 17 | if (token[0] == Token.RULE) { 18 | inSpecificSelector = !/[\.\+>~]/.test(serializeRules(token[1])); 19 | 20 | for (i = 0, l = token[2].length; i < l; i++) { 21 | property = token[2][i]; 22 | 23 | if (property[0] != Token.PROPERTY) 24 | continue; 25 | 26 | name = property[1][1]; 27 | if (name.length === 0) 28 | continue; 29 | 30 | if (name.indexOf('--') === 0) 31 | continue; 32 | 33 | value = serializeValue(property, i); 34 | 35 | properties.push([ 36 | name, 37 | value, 38 | findNameRoot(name), 39 | token[2][i], 40 | name + ':' + value, 41 | token[1], 42 | inSpecificSelector 43 | ]); 44 | } 45 | } else if (token[0] == Token.NESTED_BLOCK) { 46 | for (i = 0, l = token[2].length; i < l; i++) { 47 | properties = properties.concat(extractProperties(token[2][i])); 48 | } 49 | } 50 | 51 | return properties; 52 | } 53 | 54 | function findNameRoot(name) { 55 | if (name == 'list-style') 56 | return name; 57 | if (name.indexOf('-radius') > 0) 58 | return 'border-radius'; 59 | if (name == 'border-collapse' || name == 'border-spacing' || name == 'border-image') 60 | return name; 61 | if (name.indexOf('border-') === 0 && /^border\-\w+\-\w+$/.test(name)) 62 | return name.match(/border\-\w+/)[0]; 63 | if (name.indexOf('border-') === 0 && /^border\-\w+$/.test(name)) 64 | return 'border'; 65 | if (name.indexOf('text-') === 0) 66 | return name; 67 | if (name == '-chrome-') 68 | return name; 69 | 70 | return name.replace(/^\-\w+\-/, '').match(/([a-zA-Z]+)/)[0].toLowerCase(); 71 | } 72 | 73 | module.exports = extractProperties; 74 | -------------------------------------------------------------------------------- /vendor/clean-css/options/rounding-precision.js: -------------------------------------------------------------------------------- 1 | var override = require('../utils/override'); 2 | 3 | var INTEGER_PATTERN = /^\d+$/; 4 | 5 | var ALL_UNITS = ['*', 'all']; 6 | var DEFAULT_PRECISION = 'off'; // all precision changes are disabled 7 | var DIRECTIVES_SEPARATOR = ','; // e.g. *=5,px=3 8 | var DIRECTIVE_VALUE_SEPARATOR = '='; // e.g. *=5 9 | 10 | function roundingPrecisionFrom(source) { 11 | return override(defaults(DEFAULT_PRECISION), buildPrecisionFrom(source)); 12 | } 13 | 14 | function defaults(value) { 15 | return { 16 | 'ch': value, 17 | 'cm': value, 18 | 'em': value, 19 | 'ex': value, 20 | 'in': value, 21 | 'mm': value, 22 | 'pc': value, 23 | 'pt': value, 24 | 'px': value, 25 | 'q': value, 26 | 'rem': value, 27 | 'vh': value, 28 | 'vmax': value, 29 | 'vmin': value, 30 | 'vw': value, 31 | '%': value 32 | }; 33 | } 34 | 35 | function buildPrecisionFrom(source) { 36 | if (source === null || source === undefined) { 37 | return {}; 38 | } 39 | 40 | if (typeof source == 'boolean') { 41 | return {}; 42 | } 43 | 44 | if (typeof source == 'number' && source == -1) { 45 | return defaults(DEFAULT_PRECISION); 46 | } 47 | 48 | if (typeof source == 'number') { 49 | return defaults(source); 50 | } 51 | 52 | if (typeof source == 'string' && INTEGER_PATTERN.test(source)) { 53 | return defaults(parseInt(source)); 54 | } 55 | 56 | if (typeof source == 'string' && source == DEFAULT_PRECISION) { 57 | return defaults(DEFAULT_PRECISION); 58 | } 59 | 60 | if (typeof source == 'object') { 61 | return source; 62 | } 63 | 64 | return source 65 | .split(DIRECTIVES_SEPARATOR) 66 | .reduce(function (accumulator, directive) { 67 | var directiveParts = directive.split(DIRECTIVE_VALUE_SEPARATOR); 68 | var name = directiveParts[0]; 69 | var value = parseInt(directiveParts[1]); 70 | 71 | if (isNaN(value) || value == -1) { 72 | value = DEFAULT_PRECISION; 73 | } 74 | 75 | if (ALL_UNITS.indexOf(name) > -1) { 76 | accumulator = override(accumulator, defaults(value)); 77 | } else { 78 | accumulator[name] = value; 79 | } 80 | 81 | return accumulator; 82 | }, {}); 83 | } 84 | 85 | module.exports = { 86 | DEFAULT: DEFAULT_PRECISION, 87 | roundingPrecisionFrom: roundingPrecisionFrom 88 | }; 89 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/merge-adjacent.js: -------------------------------------------------------------------------------- 1 | var isMergeable = require('./is-mergeable'); 2 | 3 | var optimizeProperties = require('./properties/optimize'); 4 | 5 | var sortSelectors = require('../level-1/sort-selectors'); 6 | var tidyRules = require('../level-1/tidy-rules'); 7 | 8 | var OptimizationLevel = require('../../options/optimization-level').OptimizationLevel; 9 | 10 | var serializeBody = require('../../writer/one-time').body; 11 | var serializeRules = require('../../writer/one-time').rules; 12 | 13 | var Token = require('../../tokenizer/token'); 14 | 15 | function mergeAdjacent(tokens, context) { 16 | var lastToken = [null, [], []]; 17 | var options = context.options; 18 | var adjacentSpace = options.compatibility.selectors.adjacentSpace; 19 | var selectorsSortingMethod = options.level[OptimizationLevel.One].selectorsSortingMethod; 20 | var mergeablePseudoClasses = options.compatibility.selectors.mergeablePseudoClasses; 21 | var mergeablePseudoElements = options.compatibility.selectors.mergeablePseudoElements; 22 | var mergeLimit = options.compatibility.selectors.mergeLimit; 23 | var multiplePseudoMerging = options.compatibility.selectors.multiplePseudoMerging; 24 | 25 | for (var i = 0, l = tokens.length; i < l; i++) { 26 | var token = tokens[i]; 27 | 28 | if (token[0] != Token.RULE) { 29 | lastToken = [null, [], []]; 30 | continue; 31 | } 32 | 33 | if (lastToken[0] == Token.RULE && serializeRules(token[1]) == serializeRules(lastToken[1])) { 34 | Array.prototype.push.apply(lastToken[2], token[2]); 35 | optimizeProperties(lastToken[2], true, true, context); 36 | token[2] = []; 37 | } else if (lastToken[0] == Token.RULE && serializeBody(token[2]) == serializeBody(lastToken[2]) && 38 | isMergeable(serializeRules(token[1]), mergeablePseudoClasses, mergeablePseudoElements, multiplePseudoMerging) && 39 | isMergeable(serializeRules(lastToken[1]), mergeablePseudoClasses, mergeablePseudoElements, multiplePseudoMerging) && 40 | lastToken[1].length < mergeLimit) { 41 | lastToken[1] = tidyRules(lastToken[1].concat(token[1]), false, adjacentSpace, false, context.warnings); 42 | lastToken[1] = lastToken.length > 1 ? sortSelectors(lastToken[1], selectorsSortingMethod) : lastToken[1]; 43 | token[2] = []; 44 | } else { 45 | lastToken = token; 46 | } 47 | } 48 | } 49 | 50 | module.exports = mergeAdjacent; 51 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/is-allowed-resource.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var url = require('url'); 3 | 4 | var isRemoteResource = require('../utils/is-remote-resource'); 5 | var hasProtocol = require('../utils/has-protocol'); 6 | 7 | var HTTP_PROTOCOL = 'http:'; 8 | 9 | function isAllowedResource(uri, isRemote, rules) { 10 | var match; 11 | var absoluteUri; 12 | var allowed = isRemote ? false : true; 13 | var rule; 14 | var isNegated; 15 | var normalizedRule; 16 | var i; 17 | 18 | if (rules.length === 0) { 19 | return false; 20 | } 21 | 22 | if (isRemote && !hasProtocol(uri)) { 23 | uri = HTTP_PROTOCOL + uri; 24 | } 25 | 26 | match = isRemote ? 27 | url.parse(uri).host : 28 | uri; 29 | 30 | absoluteUri = isRemote ? 31 | uri : 32 | path.resolve(uri); 33 | 34 | for (i = 0; i < rules.length; i++) { 35 | rule = rules[i]; 36 | isNegated = rule[0] == '!'; 37 | normalizedRule = rule.substring(1); 38 | 39 | if (isNegated && isRemote && isRemoteRule(normalizedRule)) { 40 | allowed = allowed && !isAllowedResource(uri, true, [normalizedRule]); 41 | } else if (isNegated && !isRemote && !isRemoteRule(normalizedRule)) { 42 | allowed = allowed && !isAllowedResource(uri, false, [normalizedRule]); 43 | } else if (isNegated) { 44 | allowed = allowed && true; 45 | } else if (rule == 'all') { 46 | allowed = true; 47 | } else if (isRemote && rule == 'local') { 48 | allowed = allowed || false; 49 | } else if (isRemote && rule == 'remote') { 50 | allowed = true; 51 | } else if (!isRemote && rule == 'remote') { 52 | allowed = false; 53 | } else if (!isRemote && rule == 'local') { 54 | allowed = true; 55 | } else if (rule === match) { 56 | allowed = true; 57 | } else if (rule === uri) { 58 | allowed = true; 59 | } else if (isRemote && absoluteUri.indexOf(rule) === 0) { 60 | allowed = true; 61 | } else if (!isRemote && absoluteUri.indexOf(path.resolve(rule)) === 0) { 62 | allowed = true; 63 | } else if (isRemote != isRemoteRule(normalizedRule)) { 64 | allowed = allowed && true; 65 | } else { 66 | allowed = false; 67 | } 68 | } 69 | 70 | return allowed; 71 | } 72 | 73 | function isRemoteRule(rule) { 74 | return isRemoteResource(rule) || url.parse(HTTP_PROTOCOL + '//' + rule).host == rule; 75 | } 76 | 77 | module.exports = isAllowedResource; 78 | -------------------------------------------------------------------------------- /config.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://newfuture.github.io/miniprogram-build/config.schema.json", 4 | "type": "object", 5 | "title": "The miniprogram-build config json schema", 6 | "properties": { 7 | "production": { 8 | "$id": "#/properties/production", 9 | "type": "boolean", 10 | "title": "Release Optimization Mode", 11 | "description": "是否开启发布优化,等效 NODE_ENV=production", 12 | "default": false, 13 | "examples": [false, true] 14 | }, 15 | "src": { 16 | "$id": "#/properties/src", 17 | "type": "string", 18 | "title": "The source folder", 19 | "default": "src", 20 | "examples": ["src"], 21 | "pattern": "^[^:'\"\\*?<>|]+$" 22 | }, 23 | "dist": { 24 | "$id": "#/properties/dist", 25 | "type": "string", 26 | "title": "the output folder", 27 | "default": "dist", 28 | "examples": ["dist"], 29 | "pattern": "^[^:'\"\\*?<>|]+$" 30 | }, 31 | "assets": { 32 | "$id": "#/properties/assets", 33 | "type": "string", 34 | "title": "The Assets folder", 35 | "description": "检查文件变化和引用但不直接生成", 36 | "default": "", 37 | "examples": ["assets"], 38 | "pattern": "^[^:'\"\\*?<>|]*$" 39 | }, 40 | "copy": { 41 | "$id": "#/properties/copy", 42 | "type": "string", 43 | "title": "The copy glob (in `src`)", 44 | "description": "符合条件的文件会进行复制", 45 | "examples": ["**/*.xxx"] 46 | }, 47 | "exclude": { 48 | "$id": "#/properties/exclude", 49 | "type": ["array", "string"], 50 | "title": "The exclude glob array", 51 | "default": [], 52 | "uniqueItems": true, 53 | "items": { 54 | "type": "string" 55 | } 56 | }, 57 | "tsconfig": { 58 | "$id": "#/properties/tsconfig", 59 | "type": "string", 60 | "title": "The tsconfig.json path", 61 | "default": "", 62 | "examples": ["tsconfig.json"], 63 | "pattern": "^[^:'\"\\*?<>|]*$" 64 | }, 65 | "var": { 66 | "$id": "#/properties/var", 67 | "type": "object", 68 | "title": "The Var object", 69 | "description": "{{key}} in js and json files will be replaced", 70 | "default": {}, 71 | "properties": {} 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/specificity.js: -------------------------------------------------------------------------------- 1 | var Marker = require('../../tokenizer/marker'); 2 | 3 | var Selector = { 4 | ADJACENT_SIBLING: '+', 5 | DESCENDANT: '>', 6 | DOT: '.', 7 | HASH: '#', 8 | NON_ADJACENT_SIBLING: '~', 9 | PSEUDO: ':' 10 | }; 11 | 12 | var LETTER_PATTERN = /[a-zA-Z]/; 13 | var NOT_PREFIX = ':not('; 14 | var SEPARATOR_PATTERN = /[\s,\(>~\+]/; 15 | 16 | function specificity(selector) { 17 | var result = [0, 0, 0]; 18 | var character; 19 | var isEscaped; 20 | var isSingleQuoted; 21 | var isDoubleQuoted; 22 | var roundBracketLevel = 0; 23 | var couldIntroduceNewTypeSelector; 24 | var withinNotPseudoClass = false; 25 | var wasPseudoClass = false; 26 | var i, l; 27 | 28 | for (i = 0, l = selector.length; i < l; i++) { 29 | character = selector[i]; 30 | 31 | if (isEscaped) { 32 | // noop 33 | } else if (character == Marker.SINGLE_QUOTE && !isDoubleQuoted && !isSingleQuoted) { 34 | isSingleQuoted = true; 35 | } else if (character == Marker.SINGLE_QUOTE && !isDoubleQuoted && isSingleQuoted) { 36 | isSingleQuoted = false; 37 | } else if (character == Marker.DOUBLE_QUOTE && !isDoubleQuoted && !isSingleQuoted) { 38 | isDoubleQuoted = true; 39 | } else if (character == Marker.DOUBLE_QUOTE && isDoubleQuoted && !isSingleQuoted) { 40 | isDoubleQuoted = false; 41 | } else if (isSingleQuoted || isDoubleQuoted) { 42 | continue; 43 | } else if (roundBracketLevel > 0 && !withinNotPseudoClass) { 44 | // noop 45 | } else if (character == Marker.OPEN_ROUND_BRACKET) { 46 | roundBracketLevel++; 47 | } else if (character == Marker.CLOSE_ROUND_BRACKET && roundBracketLevel == 1) { 48 | roundBracketLevel--; 49 | withinNotPseudoClass = false; 50 | } else if (character == Marker.CLOSE_ROUND_BRACKET) { 51 | roundBracketLevel--; 52 | } else if (character == Selector.HASH) { 53 | result[0]++; 54 | } else if (character == Selector.DOT || character == Marker.OPEN_SQUARE_BRACKET) { 55 | result[1]++; 56 | } else if (character == Selector.PSEUDO && !wasPseudoClass && !isNotPseudoClass(selector, i)) { 57 | result[1]++; 58 | withinNotPseudoClass = false; 59 | } else if (character == Selector.PSEUDO) { 60 | withinNotPseudoClass = true; 61 | } else if ((i === 0 || couldIntroduceNewTypeSelector) && LETTER_PATTERN.test(character)) { 62 | result[2]++; 63 | } 64 | 65 | isEscaped = character == Marker.BACK_SLASH; 66 | wasPseudoClass = character == Selector.PSEUDO; 67 | couldIntroduceNewTypeSelector = !isEscaped && SEPARATOR_PATTERN.test(character); 68 | } 69 | 70 | return result; 71 | } 72 | 73 | function isNotPseudoClass(selector, index) { 74 | return selector.indexOf(NOT_PREFIX, index) === index; 75 | } 76 | 77 | module.exports = specificity; 78 | -------------------------------------------------------------------------------- /src/tasks/npm.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | var path = require('path'); 4 | 5 | var gulp = require('gulp'); 6 | var fs = require('fs'); 7 | var colors = require('ansi-colors'); 8 | 9 | var log = require('../log/logger'); 10 | const color = require('../log/color'); 11 | 12 | var unlink = require('../lib/unlink'); 13 | const npm = require('../lib/npm-dependency'); 14 | 15 | var buildNpm = require('../compiler/build-npm'); 16 | // var npmInstall = require('../compiler/npm-install'); 17 | // var copy = require('../compiler/copy'); 18 | // var rollup = require('rollup') 19 | var watchLog = require('../log/watch'); 20 | // var merge = require('merge-stream'); 21 | 22 | 23 | var PACKAGE_JSON = 'package.json'; 24 | /** 25 | * @param {object} config 26 | */ 27 | exports.build = function (config) { 28 | return function (cb) { 29 | fs.exists(PACKAGE_JSON, function (is_json_exists) { 30 | if (!is_json_exists) { 31 | cb && cb(); 32 | } else { 33 | try { 34 | const dependencies = npm.getDependencies(process.cwd()); 35 | if (dependencies && Object.keys(dependencies).length > 0) { 36 | fs.exists('node_modules', function (is_modules_exists) { 37 | if (!is_modules_exists) { 38 | log.error( 39 | color('npm:'), 40 | colors.yellowBright('node_modules/ doesn\'t exist! please run `' + colors.bgRedBright('npm i') + '`'), 41 | ); 42 | cb && cb(new Error("node_modules/ doesn't exist!")); 43 | 44 | } else { 45 | return buildNpm(process.cwd(), config.dist, Object.keys(dependencies))(cb); 46 | } 47 | }); 48 | } else { 49 | log.info( 50 | color('npm:'), 51 | colors.gray('No `dependency` was found. Skips!') 52 | ); 53 | cb && cb(); 54 | } 55 | } catch (error) { 56 | log.error(error); 57 | cb && cb(error); 58 | } 59 | } 60 | }) 61 | }; 62 | } 63 | 64 | /** 65 | * @param {object} config 66 | */ 67 | exports.watch = function (config) { 68 | return function (cb) { 69 | watchLog('npm', PACKAGE_JSON); 70 | gulp.watch(PACKAGE_JSON, { delay: 1200, ignorePermissionErrors: true }) 71 | .on('change', function () { exports.build(config)(); }) 72 | .on('add', function () { exports.build(config)(); }) 73 | .on('unlink', unlink("miniprogram_npm", config.dist)); 74 | cb && cb(); 75 | } 76 | } -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/merge-non-adjacent-by-selector.js: -------------------------------------------------------------------------------- 1 | var canReorder = require('./reorderable').canReorder; 2 | var extractProperties = require('./extract-properties'); 3 | 4 | var optimizeProperties = require('./properties/optimize'); 5 | 6 | var serializeRules = require('../../writer/one-time').rules; 7 | 8 | var Token = require('../../tokenizer/token'); 9 | 10 | function mergeNonAdjacentBySelector(tokens, context) { 11 | var specificityCache = context.cache.specificity; 12 | var allSelectors = {}; 13 | var repeatedSelectors = []; 14 | var i; 15 | 16 | for (i = tokens.length - 1; i >= 0; i--) { 17 | if (tokens[i][0] != Token.RULE) 18 | continue; 19 | if (tokens[i][2].length === 0) 20 | continue; 21 | 22 | var selector = serializeRules(tokens[i][1]); 23 | allSelectors[selector] = [i].concat(allSelectors[selector] || []); 24 | 25 | if (allSelectors[selector].length == 2) 26 | repeatedSelectors.push(selector); 27 | } 28 | 29 | for (i = repeatedSelectors.length - 1; i >= 0; i--) { 30 | var positions = allSelectors[repeatedSelectors[i]]; 31 | 32 | selectorIterator: 33 | for (var j = positions.length - 1; j > 0; j--) { 34 | var positionOne = positions[j - 1]; 35 | var tokenOne = tokens[positionOne]; 36 | var positionTwo = positions[j]; 37 | var tokenTwo = tokens[positionTwo]; 38 | 39 | directionIterator: 40 | for (var direction = 1; direction >= -1; direction -= 2) { 41 | var topToBottom = direction == 1; 42 | var from = topToBottom ? positionOne + 1 : positionTwo - 1; 43 | var to = topToBottom ? positionTwo : positionOne; 44 | var delta = topToBottom ? 1 : -1; 45 | var moved = topToBottom ? tokenOne : tokenTwo; 46 | var target = topToBottom ? tokenTwo : tokenOne; 47 | var movedProperties = extractProperties(moved); 48 | 49 | while (from != to) { 50 | var traversedProperties = extractProperties(tokens[from]); 51 | from += delta; 52 | 53 | // traversed then moved as we move selectors towards the start 54 | var reorderable = topToBottom ? 55 | canReorder(movedProperties, traversedProperties, specificityCache) : 56 | canReorder(traversedProperties, movedProperties, specificityCache); 57 | 58 | if (!reorderable && !topToBottom) 59 | continue selectorIterator; 60 | if (!reorderable && topToBottom) 61 | continue directionIterator; 62 | } 63 | 64 | if (topToBottom) { 65 | Array.prototype.push.apply(moved[2], target[2]); 66 | target[2] = moved[2]; 67 | } else { 68 | Array.prototype.push.apply(target[2], moved[2]); 69 | } 70 | 71 | optimizeProperties(target[2], true, true, context); 72 | moved[2] = []; 73 | } 74 | } 75 | } 76 | } 77 | 78 | module.exports = mergeNonAdjacentBySelector; 79 | -------------------------------------------------------------------------------- /src/log/compile.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | 4 | const path = require('path'); 5 | const through = require('through2'); 6 | // const stringifyObject = require('stringify-object'); 7 | const chalk = require('ansi-colors'); 8 | const titleColor = require('./color'); 9 | const fancyLog = require('./logger'); 10 | 11 | const inputStyle = chalk.cyan.bold.underline; 12 | function outputStyle(str) { 13 | if (str) { 14 | return chalk.gray(" → ") + chalk.underline.bold.gray(str); 15 | } 16 | return ''; 17 | } 18 | 19 | const home = require('os').homedir(); 20 | 21 | function tildify(str) { 22 | str = path.normalize(str) + path.sep; 23 | return (str.indexOf(home) === 0 ? str.replace(home + path.sep, '~' + path.sep) : str).slice(0, -1); 24 | }; 25 | 26 | module.exports = options => { 27 | options = Object.assign({ 28 | logger: fancyLog, 29 | title: 'mp-build:', 30 | minimal: true, 31 | showFiles: true, 32 | showCount: false 33 | }, options); 34 | 35 | if (process.argv.includes('--verbose')) { 36 | options.verbose = true; 37 | options.minimal = false; 38 | options.showFiles = true; 39 | options.showCount = true; 40 | } 41 | 42 | let count = 0; 43 | 44 | return through.obj((file, enc, cb) => { 45 | if (options.showFiles) { 46 | let output = chalk.whiteBright.bold(chalk.symbols.pointer) + ' '; 47 | const name = path.relative(file.base, file.path); 48 | if (options.minimal) { 49 | output += inputStyle(options.srcName || name); 50 | } else { 51 | output = 52 | '\n' + 53 | (file.cwd ? 'cwd: ' + inputStyle(tildify(file.cwd)) : '') + 54 | (file.base ? '\nbase: ' + inputStyle(tildify(file.base)) : '') + 55 | (file.path ? '\npath: ' + inputStyle(tildify(file.path)) : '') + 56 | // (file.stat && options.verbose ? '\nstat: ' + prop(stringifyObject(file.stat, { indent: ' ' }).replace(/[{}]/g, '').trim()) : '') + 57 | '\n'; 58 | } 59 | 60 | // let outPath = '' 61 | if (options.distName) { 62 | output += outputStyle(options.distName); 63 | } else if (options.distExt || options.dist) { 64 | output += outputStyle( 65 | path.join( 66 | options.dist || '', 67 | name.replace(/\.(.*)$/, options.distExt || '.$1') 68 | ) 69 | ); 70 | } 71 | 72 | options.logger(titleColor(options.title), output || chalk.gray('…')); 73 | } 74 | 75 | count++; 76 | cb(null, file); 77 | }, cb => { 78 | if (options.showCount) { 79 | options.logger(titleColor(options.title), chalk.green(count + ' ' + (count > 0 ? 'items' : 'item'))); 80 | } 81 | cb(); 82 | }); 83 | }; 84 | -------------------------------------------------------------------------------- /src/log/size.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | 4 | const through = require('through2'); 5 | const chalk = require('ansi-colors'); 6 | const PluginError = require('../lib/error'); 7 | const prettyBytes = require('../lib/pretty-bytes'); 8 | const prettyTime = require('../lib/pretty-time'); 9 | 10 | const StreamCounter = require('../lib/byte-counter'); 11 | const titleColor = require('./color'); 12 | const fancyLog = require('./logger'); 13 | 14 | 15 | 16 | module.exports = opts => { 17 | opts = Object.assign({ 18 | pretty: true, 19 | showTotal: true 20 | }, opts); 21 | 22 | let totalSize = 0; 23 | let fileCount = 0; 24 | const time = process.hrtime(); 25 | 26 | function log(sym, what, size, duration, highlightSize) { 27 | let title = opts.title; 28 | title = title ? titleColor(title) : ''; 29 | if (opts.sub) { 30 | sym += chalk.cyanBright(` <${chalk.bold.underline(opts.sub)}>`); 31 | } 32 | size = opts.pretty ? prettyBytes(size) : (size + ' B'); 33 | duration = duration ? chalk.gray("[" + prettyTime(duration) + "]") : ''; 34 | fancyLog(title , sym , what, chalk.gray('(') + chalk[highlightSize ? 'magentaBright' : 'gray'](size) + chalk.gray(')') + duration); 35 | } 36 | 37 | return through.obj((file, enc, cb) => { 38 | if (file.isNull()) { 39 | cb(null, file); 40 | return; 41 | } 42 | 43 | const finish = (err, size) => { 44 | if (err) { 45 | cb(new PluginError('size', err)); 46 | return; 47 | } 48 | 49 | totalSize += size; 50 | 51 | if (opts.showFiles === true && size > 0) { 52 | log( 53 | chalk.reset.whiteBright.dim(chalk.symbols.check), 54 | chalk.green.underline.bold(opts.showTotal ? chalk.dim(file.relative) : file.relative), 55 | size, 56 | !opts.showTotal); 57 | } 58 | 59 | fileCount++; 60 | cb(null, file); 61 | }; 62 | 63 | if (file.isStream()) { 64 | 65 | file.contents.pipe(new StreamCounter()) 66 | .on('error', finish) 67 | .on('finish', function () { 68 | finish(null, this.bytes); 69 | }); 70 | return; 71 | } 72 | 73 | 74 | finish(null, file.contents.length); 75 | 76 | }, function (cb) { 77 | // @ts-ignore 78 | this.size = totalSize; 79 | // @ts-ignore 80 | this.prettySize = prettyBytes(totalSize); 81 | 82 | if (!(fileCount === 1 && opts.showFiles) && totalSize > 0 && fileCount > 0 && opts.showTotal) { 83 | const diff = process.hrtime(time); 84 | const duration = diff[0] * 1e9 + diff[1] 85 | log(chalk.reset.bold.greenBright.italic(chalk.symbols.check), chalk.green('All ' + fileCount + (fileCount > 1 ? ' files' : ' file') + ' done!'), totalSize, duration, true); 86 | } 87 | cb(); 88 | }); 89 | }; -------------------------------------------------------------------------------- /vendor/clean-css/reader/rebase.js: -------------------------------------------------------------------------------- 1 | var extractImportUrlAndMedia = require('./extract-import-url-and-media'); 2 | var restoreImport = require('./restore-import'); 3 | var rewriteUrl = require('./rewrite-url'); 4 | 5 | var Token = require('../tokenizer/token'); 6 | var isImport = require('../utils/is-import'); 7 | 8 | var SOURCE_MAP_COMMENT_PATTERN = /^\/\*# sourceMappingURL=(\S+) \*\/$/; 9 | 10 | function rebase(tokens, rebaseAll, validator, rebaseConfig) { 11 | return rebaseAll ? 12 | rebaseEverything(tokens, validator, rebaseConfig) : 13 | rebaseAtRules(tokens, validator, rebaseConfig); 14 | } 15 | 16 | function rebaseEverything(tokens, validator, rebaseConfig) { 17 | var token; 18 | var i, l; 19 | 20 | for (i = 0, l = tokens.length; i < l; i++) { 21 | token = tokens[i]; 22 | 23 | switch (token[0]) { 24 | case Token.AT_RULE: 25 | rebaseAtRule(token, validator, rebaseConfig); 26 | break; 27 | case Token.AT_RULE_BLOCK: 28 | rebaseProperties(token[2], validator, rebaseConfig); 29 | break; 30 | case Token.COMMENT: 31 | rebaseSourceMapComment(token, rebaseConfig); 32 | break; 33 | case Token.NESTED_BLOCK: 34 | rebaseEverything(token[2], validator, rebaseConfig); 35 | break; 36 | case Token.RULE: 37 | rebaseProperties(token[2], validator, rebaseConfig); 38 | break; 39 | } 40 | } 41 | 42 | return tokens; 43 | } 44 | 45 | function rebaseAtRules(tokens, validator, rebaseConfig) { 46 | var token; 47 | var i, l; 48 | 49 | for (i = 0, l = tokens.length; i < l; i++) { 50 | token = tokens[i]; 51 | 52 | switch (token[0]) { 53 | case Token.AT_RULE: 54 | rebaseAtRule(token, validator, rebaseConfig); 55 | break; 56 | } 57 | } 58 | 59 | return tokens; 60 | } 61 | 62 | function rebaseAtRule(token, validator, rebaseConfig) { 63 | if (!isImport(token[1])) { 64 | return; 65 | } 66 | 67 | var uriAndMediaQuery = extractImportUrlAndMedia(token[1]); 68 | var newUrl = rewriteUrl(uriAndMediaQuery[0], rebaseConfig); 69 | var mediaQuery = uriAndMediaQuery[1]; 70 | 71 | token[1] = restoreImport(newUrl, mediaQuery); 72 | } 73 | 74 | function rebaseSourceMapComment(token, rebaseConfig) { 75 | var matches = SOURCE_MAP_COMMENT_PATTERN.exec(token[1]); 76 | 77 | if (matches && matches[1].indexOf('data:') === -1) { 78 | token[1] = token[1].replace(matches[1], rewriteUrl(matches[1], rebaseConfig, true)); 79 | } 80 | } 81 | 82 | function rebaseProperties(properties, validator, rebaseConfig) { 83 | var property; 84 | var value; 85 | var i, l; 86 | var j, m; 87 | 88 | for (i = 0, l = properties.length; i < l; i++) { 89 | property = properties[i]; 90 | 91 | for (j = 2 /* 0 is Token.PROPERTY, 1 is name */, m = property.length; j < m; j++) { 92 | value = property[j][1]; 93 | 94 | if (validator.isUrl(value)) { 95 | property[j][1] = rewriteUrl(value, rebaseConfig); 96 | } 97 | } 98 | } 99 | } 100 | 101 | module.exports = rebase; 102 | -------------------------------------------------------------------------------- /src/lib/multi-replace.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 'use strict'; 3 | var through = require('through2'); 4 | var path = require('path'); 5 | var colors = require('ansi-colors'); 6 | 7 | var log = require('../log/logger'); 8 | var TITLE = 'replace' 9 | 10 | /** 11 | * 12 | * @param {number} n 13 | * @param {string|RegExp} key 14 | * @param {*} value 15 | * @param {object} file 16 | */ 17 | function logReplace(n, key, value, file) { 18 | log.info( 19 | colors.gray(TITLE), 20 | colors.gray.bold(colors.symbols.check.repeat(n)), 21 | colors.gray.dim.italic.strikethrough(key.toString()), 22 | colors.dim.gray(colors.symbols.pointerSmall), 23 | typeof value === 'function' ? colors.cyan(colors.italic('Function:') + (value.name || '')) : colors.underline(value), 24 | colors.gray('(' + colors.underline( 25 | path.relative(file.base, file.path) 26 | ) + ')') 27 | ) 28 | } 29 | 30 | /** 31 | * 批量替换字符串 32 | * @param {object|string|RegExp} opts 33 | * @param {string|Function} [replacement] 34 | * @param {string} [prefix] 35 | * @param {string} [suffix] 36 | */ 37 | function multiReplace(opts, replacement, prefix, suffix) { 38 | function replace(file, encoding, callback) { 39 | var str = file.contents.toString(); 40 | prefix = prefix || ''; 41 | suffix = suffix || ''; 42 | if (file.isBuffer()) { 43 | if (replacement === undefined) { 44 | console.assert(typeof opts === 'object', 'replace opts should object') 45 | for (var key in opts) { 46 | var search_key = prefix + key + suffix; 47 | var sp = str.split(search_key); 48 | if (sp.length > 1) { 49 | str = sp.join(opts[key]); 50 | logReplace(sp.length - 1, search_key, opts[key], file); 51 | } 52 | } 53 | } else if (opts instanceof RegExp) { 54 | //正则表达式 55 | /** 56 | * @type {number} 57 | */ 58 | var n = (str.match(opts) || []).length; 59 | if (n > 0) { 60 | str = str.replace(opts, replacement); 61 | logReplace(n, opts, replacement, file); 62 | } 63 | } else { 64 | // 字符串 65 | var search_key = prefix + opts + suffix; 66 | var n = str.split(search_key).length - 1; 67 | if (n > 0) { 68 | //@ts-ignore 69 | str = str.replace(new RegExp(search_key, 'mg'), replacement); 70 | logReplace(n, search_key, replacement, file); 71 | } 72 | 73 | } 74 | file.contents = Buffer.from(str); 75 | } else if (file.isStream()) { 76 | console.error('Streaming not supported') 77 | this.emit('error', 'replace:Streaming not supported'); 78 | return callback('Streaming not supported', file); 79 | } 80 | callback(null, file); 81 | } 82 | 83 | return through.obj(replace); 84 | }; 85 | module.exports = multiReplace; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "miniprogram-build", 3 | "version": "8.0.0.beta.1", 4 | "description": "A command line tool to build & watch MiniProgram.", 5 | "keywords": [ 6 | "MiniProgram", 7 | "build", 8 | "typescript", 9 | "wechat", 10 | "scss", 11 | "tools", 12 | "gulp", 13 | "npm", 14 | "framework", 15 | "小程序", 16 | "微信" 17 | ], 18 | "main": "src/task.js", 19 | "bin": { 20 | "miniprogram-build": "bin/mp-build.js", 21 | "mp-build": "bin/mp-build.js", 22 | "mp": "bin/mp-build.js" 23 | }, 24 | "engines": { 25 | "node": ">=10" 26 | }, 27 | "files": [ 28 | "src/", 29 | "vendor/", 30 | "bin/" 31 | ], 32 | "scripts": { 33 | "version": "conventional-changelog -r 0 -p angular -i CHANGELOG.md -s && git add CHANGELOG.md", 34 | "postversion": "git push --follow-tags -q", 35 | "test:empty": "cd test-empty && node ../bin/mp-build.js build && node ../bin/mp-build.js compile --release", 36 | "test:empty-ts": "cd test-ts && node ../bin/mp-build.js build && node ../bin/mp-build.js compile --release", 37 | "test:full": "npm test --prefix=test", 38 | "test": "npm run test:empty && npm run test:full && npm run test:empty-ts" 39 | }, 40 | "repository": { 41 | "type": "git", 42 | "url": "git+https://github.com/NewFuture/miniprogram-build.git" 43 | }, 44 | "author": { 45 | "name": "NewFuture", 46 | "email": "npm@newfuture.cc", 47 | "url": "https://newfuture.cc" 48 | }, 49 | "license": "MIT", 50 | "bugs": { 51 | "url": "https://github.com/NewFuture/miniprogram-build/issues" 52 | }, 53 | "homepage": "https://github.com/NewFuture/miniprogram-build#readme", 54 | "dependencies": { 55 | "ansi-colors": "^4.1.3", 56 | "gulp": "^4.0.2", 57 | "gulp-better-rollup": "^4.0.1", 58 | "gulp-rename": "^2.0.0", 59 | "gulp-sourcemaps": "^3.0.0", 60 | "gulp-typescript": "^5.0.1", 61 | "imagemin": "^7.0.1", 62 | "json5": "^2.2.1", 63 | "mime": "^2.4.6", 64 | "rimraf": "^3.0.2", 65 | "rollup": "^2.79.0", 66 | "sass": "^1.54.8", 67 | "through2": "^4.0.2", 68 | "ts-transform-paths": "^2.0.3", 69 | "wechat-devtool": "^2.0.0", 70 | "yargs": "~15.3.1" 71 | }, 72 | "optionalDependencies": { 73 | "@rollup/plugin-commonjs": "^15.0.0", 74 | "@rollup/plugin-json": "^4.1.0", 75 | "@rollup/plugin-node-resolve": "^9.0.0", 76 | "@rollup/plugin-replace": "^2.3.0", 77 | "@rollup/plugin-typescript": "^2.1.0", 78 | "imagemin-gifsicle": "^7.0.0", 79 | "imagemin-jpegtran": "^7.0.0", 80 | "imagemin-optipng": "^8.0.0", 81 | "imagemin-svgo": "^8.0.0" 82 | }, 83 | "peerDependencies": { 84 | "tslib": ">=1.7", 85 | "typescript": ">=2.7.1" 86 | }, 87 | "devDependencies": { 88 | "@types/gulp": "^4.0.6", 89 | "@types/rimraf": "^3.0.0", 90 | "conventional-changelog-cli": "^2.1.0", 91 | "tslib": "^2.0.0", 92 | "typescript": "^4.0.2" 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/merge-non-adjacent-by-body.js: -------------------------------------------------------------------------------- 1 | var isMergeable = require('./is-mergeable'); 2 | 3 | var sortSelectors = require('../level-1/sort-selectors'); 4 | var tidyRules = require('../level-1/tidy-rules'); 5 | 6 | var OptimizationLevel = require('../../options/optimization-level').OptimizationLevel; 7 | 8 | var serializeBody = require('../../writer/one-time').body; 9 | var serializeRules = require('../../writer/one-time').rules; 10 | 11 | var Token = require('../../tokenizer/token'); 12 | 13 | function unsafeSelector(value) { 14 | return /\.|\*| :/.test(value); 15 | } 16 | 17 | function isBemElement(token) { 18 | var asString = serializeRules(token[1]); 19 | return asString.indexOf('__') > -1 || asString.indexOf('--') > -1; 20 | } 21 | 22 | function withoutModifier(selector) { 23 | return selector.replace(/--[^ ,>\+~:]+/g, ''); 24 | } 25 | 26 | function removeAnyUnsafeElements(left, candidates) { 27 | var leftSelector = withoutModifier(serializeRules(left[1])); 28 | 29 | for (var body in candidates) { 30 | var right = candidates[body]; 31 | var rightSelector = withoutModifier(serializeRules(right[1])); 32 | 33 | if (rightSelector.indexOf(leftSelector) > -1 || leftSelector.indexOf(rightSelector) > -1) 34 | delete candidates[body]; 35 | } 36 | } 37 | 38 | function mergeNonAdjacentByBody(tokens, context) { 39 | var options = context.options; 40 | var mergeSemantically = options.level[OptimizationLevel.Two].mergeSemantically; 41 | var adjacentSpace = options.compatibility.selectors.adjacentSpace; 42 | var selectorsSortingMethod = options.level[OptimizationLevel.One].selectorsSortingMethod; 43 | var mergeablePseudoClasses = options.compatibility.selectors.mergeablePseudoClasses; 44 | var mergeablePseudoElements = options.compatibility.selectors.mergeablePseudoElements; 45 | var multiplePseudoMerging = options.compatibility.selectors.multiplePseudoMerging; 46 | var candidates = {}; 47 | 48 | for (var i = tokens.length - 1; i >= 0; i--) { 49 | var token = tokens[i]; 50 | if (token[0] != Token.RULE) 51 | continue; 52 | 53 | if (token[2].length > 0 && (!mergeSemantically && unsafeSelector(serializeRules(token[1])))) 54 | candidates = {}; 55 | 56 | if (token[2].length > 0 && mergeSemantically && isBemElement(token)) 57 | removeAnyUnsafeElements(token, candidates); 58 | 59 | var candidateBody = serializeBody(token[2]); 60 | var oldToken = candidates[candidateBody]; 61 | if (oldToken && 62 | isMergeable(serializeRules(token[1]), mergeablePseudoClasses, mergeablePseudoElements, multiplePseudoMerging) && 63 | isMergeable(serializeRules(oldToken[1]), mergeablePseudoClasses, mergeablePseudoElements, multiplePseudoMerging)) { 64 | 65 | if (token[2].length > 0) { 66 | token[1] = tidyRules(oldToken[1].concat(token[1]), false, adjacentSpace, false, context.warnings); 67 | token[1] = token[1].length > 1 ? sortSelectors(token[1], selectorsSortingMethod) : token[1]; 68 | } else { 69 | token[1] = oldToken[1].concat(token[1]); 70 | } 71 | 72 | oldToken[2] = []; 73 | candidates[candidateBody] = null; 74 | } 75 | 76 | candidates[serializeBody(token[2])] = token; 77 | } 78 | } 79 | 80 | module.exports = mergeNonAdjacentByBody; 81 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/rewrite-url.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var url = require('url'); 3 | 4 | var DOUBLE_QUOTE = '"'; 5 | var SINGLE_QUOTE = '\''; 6 | var URL_PREFIX = 'url('; 7 | var URL_SUFFIX = ')'; 8 | 9 | var QUOTE_PREFIX_PATTERN = /^["']/; 10 | var QUOTE_SUFFIX_PATTERN = /["']$/; 11 | var ROUND_BRACKETS_PATTERN = /[\(\)]/; 12 | var URL_PREFIX_PATTERN = /^url\(/i; 13 | var URL_SUFFIX_PATTERN = /\)$/; 14 | var WHITESPACE_PATTERN = /\s/; 15 | 16 | var isWindows = process.platform == 'win32'; 17 | 18 | function rebase(uri, rebaseConfig) { 19 | if (!rebaseConfig) { 20 | return uri; 21 | } 22 | 23 | if (isAbsolute(uri) && !isRemote(rebaseConfig.toBase)) { 24 | return uri; 25 | } 26 | 27 | if (isRemote(uri) || isSVGMarker(uri) || isInternal(uri)) { 28 | return uri; 29 | } 30 | 31 | if (isData(uri)) { 32 | return '\'' + uri + '\''; 33 | } 34 | 35 | if (isRemote(rebaseConfig.toBase)) { 36 | return url.resolve(rebaseConfig.toBase, uri); 37 | } 38 | 39 | return rebaseConfig.absolute ? 40 | normalize(absolute(uri, rebaseConfig)) : 41 | normalize(relative(uri, rebaseConfig)); 42 | } 43 | 44 | function isAbsolute(uri) { 45 | return path.isAbsolute(uri); 46 | } 47 | 48 | function isSVGMarker(uri) { 49 | return uri[0] == '#'; 50 | } 51 | 52 | function isInternal(uri) { 53 | return /^\w+:\w+/.test(uri); 54 | } 55 | 56 | function isRemote(uri) { 57 | return /^[^:]+?:\/\//.test(uri) || uri.indexOf('//') === 0; 58 | } 59 | 60 | function isData(uri) { 61 | return uri.indexOf('data:') === 0; 62 | } 63 | 64 | function absolute(uri, rebaseConfig) { 65 | return path 66 | .resolve(path.join(rebaseConfig.fromBase || '', uri)) 67 | .replace(rebaseConfig.toBase, ''); 68 | } 69 | 70 | function relative(uri, rebaseConfig) { 71 | return path.relative(rebaseConfig.toBase, path.join(rebaseConfig.fromBase || '', uri)); 72 | } 73 | 74 | function normalize(uri) { 75 | return isWindows ? uri.replace(/\\/g, '/') : uri; 76 | } 77 | 78 | function quoteFor(unquotedUrl) { 79 | if (unquotedUrl.indexOf(SINGLE_QUOTE) > -1) { 80 | return DOUBLE_QUOTE; 81 | } else if (unquotedUrl.indexOf(DOUBLE_QUOTE) > -1) { 82 | return SINGLE_QUOTE; 83 | } else if (hasWhitespace(unquotedUrl) || hasRoundBrackets(unquotedUrl)) { 84 | return SINGLE_QUOTE; 85 | } else { 86 | return ''; 87 | } 88 | } 89 | 90 | function hasWhitespace(url) { 91 | return WHITESPACE_PATTERN.test(url); 92 | } 93 | 94 | function hasRoundBrackets(url) { 95 | return ROUND_BRACKETS_PATTERN.test(url); 96 | } 97 | 98 | function rewriteUrl(originalUrl, rebaseConfig, pathOnly) { 99 | var strippedUrl = originalUrl 100 | .replace(URL_PREFIX_PATTERN, '') 101 | .replace(URL_SUFFIX_PATTERN, '') 102 | .trim(); 103 | 104 | var unquotedUrl = strippedUrl 105 | .replace(QUOTE_PREFIX_PATTERN, '') 106 | .replace(QUOTE_SUFFIX_PATTERN, '') 107 | .trim(); 108 | 109 | var quote = strippedUrl[0] == SINGLE_QUOTE || strippedUrl[0] == DOUBLE_QUOTE ? 110 | strippedUrl[0] : 111 | quoteFor(unquotedUrl); 112 | 113 | return pathOnly ? 114 | rebase(unquotedUrl, rebaseConfig) : 115 | URL_PREFIX + quote + rebase(unquotedUrl, rebaseConfig) + quote + URL_SUFFIX; 116 | } 117 | 118 | module.exports = rewriteUrl; 119 | -------------------------------------------------------------------------------- /vendor/clean-css/writer/source-maps.js: -------------------------------------------------------------------------------- 1 | var SourceMapGenerator = require('source-map').SourceMapGenerator; 2 | var all = require('./helpers').all; 3 | 4 | var isRemoteResource = require('../utils/is-remote-resource'); 5 | 6 | var isWindows = process.platform == 'win32'; 7 | 8 | var NIX_SEPARATOR_PATTERN = /\//g; 9 | var UNKNOWN_SOURCE = '$stdin'; 10 | var WINDOWS_SEPARATOR = '\\'; 11 | 12 | function store(serializeContext, element) { 13 | var fromString = typeof element == 'string'; 14 | var value = fromString ? element : element[1]; 15 | var mappings = fromString ? null : element[2]; 16 | var wrap = serializeContext.wrap; 17 | 18 | wrap(serializeContext, value); 19 | track(serializeContext, value, mappings); 20 | serializeContext.output.push(value); 21 | } 22 | 23 | function wrap(serializeContext, value) { 24 | if (serializeContext.column + value.length > serializeContext.format.wrapAt) { 25 | track(serializeContext, serializeContext.format.breakWith, false); 26 | serializeContext.output.push(serializeContext.format.breakWith); 27 | } 28 | } 29 | 30 | function track(serializeContext, value, mappings) { 31 | var parts = value.split('\n'); 32 | 33 | if (mappings) { 34 | trackAllMappings(serializeContext, mappings); 35 | } 36 | 37 | serializeContext.line += parts.length - 1; 38 | serializeContext.column = parts.length > 1 ? 0 : (serializeContext.column + parts.pop().length); 39 | } 40 | 41 | function trackAllMappings(serializeContext, mappings) { 42 | for (var i = 0, l = mappings.length; i < l; i++) { 43 | trackMapping(serializeContext, mappings[i]); 44 | } 45 | } 46 | 47 | function trackMapping(serializeContext, mapping) { 48 | var line = mapping[0]; 49 | var column = mapping[1]; 50 | var originalSource = mapping[2]; 51 | var source = originalSource; 52 | var storedSource = source || UNKNOWN_SOURCE; 53 | 54 | if (isWindows && source && !isRemoteResource(source)) { 55 | storedSource = source.replace(NIX_SEPARATOR_PATTERN, WINDOWS_SEPARATOR); 56 | } 57 | 58 | serializeContext.outputMap.addMapping({ 59 | generated: { 60 | line: serializeContext.line, 61 | column: serializeContext.column 62 | }, 63 | source: storedSource, 64 | original: { 65 | line: line, 66 | column: column 67 | } 68 | }); 69 | 70 | if (serializeContext.inlineSources && (originalSource in serializeContext.sourcesContent)) { 71 | serializeContext.outputMap.setSourceContent(storedSource, serializeContext.sourcesContent[originalSource]); 72 | } 73 | } 74 | 75 | function serializeStylesAndSourceMap(tokens, context) { 76 | var serializeContext = { 77 | column: 0, 78 | format: context.options.format, 79 | indentBy: 0, 80 | indentWith: '', 81 | inlineSources: context.options.sourceMapInlineSources, 82 | line: 1, 83 | output: [], 84 | outputMap: new SourceMapGenerator(), 85 | sourcesContent: context.sourcesContent, 86 | spaceAfterClosingBrace: context.options.compatibility.properties.spaceAfterClosingBrace, 87 | store: store, 88 | wrap: context.options.format.wrapAt ? 89 | wrap : 90 | function () { /* noop */ } 91 | }; 92 | 93 | all(serializeContext, tokens); 94 | 95 | return { 96 | sourceMap: serializeContext.outputMap, 97 | styles: serializeContext.output.join('') 98 | }; 99 | } 100 | 101 | module.exports = serializeStylesAndSourceMap; 102 | -------------------------------------------------------------------------------- /src/compiler/compile-wxts.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | var gulp = require("gulp"); 4 | var sourcemaps = require("gulp-sourcemaps"); 5 | var rename = require("gulp-rename"); 6 | const debug = require("../log/compile"); 7 | const size = require("../log/size"); 8 | var empty = require("../lib/empty"); 9 | var replace = require("../lib/multi-replace"); 10 | const pkgVar = require('../lib/package-var'); 11 | const loadPlugins = require("../lib/rollup-plugins"); 12 | var error = require("../log/error"); 13 | const warn = require("../log/warn"); 14 | const npm = require("../lib/npm-dependency"); 15 | 16 | const wxtsConfig = { 17 | rootDir: undefined, 18 | include: ["**/*.wxts", "**/*.ts"], 19 | target: "es5", 20 | module: "ES6", 21 | downlevelIteration: true, //Provide full support for iterables in for..of, spread and destructuring when targeting ES5 or ES3. 22 | isolatedModules: true, //Transpile each file as a separate module (similar to “ts.transpileModule”). 23 | // noLib: true, 24 | lib: ["es5"], 25 | }; 26 | 27 | const defaultConfig = { 28 | // allowJs: true, 29 | // checkJs: true, 30 | alwaysStrict: true, 31 | noImplicitAny: true, 32 | noImplicitReturns: true, 33 | noImplicitThis: true, 34 | // noUnusedLocals: true, 35 | // noUnusedParameters: true, 36 | // strictBindCallApply: true, 37 | // strictFunctionTypes: true, 38 | // strictPropertyInitialization: true, 39 | strictNullChecks: true, 40 | }; 41 | var TITLE = "wxts"; 42 | /** 43 | * 编译TS 44 | * @param {object} config * 45 | * @param {string|string[]} tsFile 46 | * @param {any} tsconfig 47 | */ 48 | function compileWxts(config, tsFile, tsconfig) { 49 | const ts = require("@rollup/plugin-typescript"); 50 | const gulpRollup = require("gulp-better-rollup"); 51 | let dependencies = [] 52 | const plugins = [].concat(loadPlugins()) 53 | 54 | try { 55 | dependencies = Object.keys(npm.getDependencies(process.cwd())); 56 | const newConfig = Object.assign({}, defaultConfig, tsconfig ? tsconfig.compilerOptions : {}, wxtsConfig); 57 | plugins.unshift(ts(newConfig)) 58 | } catch (error) { 59 | warn(TITLE)('' + error); 60 | } 61 | return gulp 62 | .src(tsFile, { base: config.src, sourcemaps: !config.production, ignore: config.exclude }) 63 | .pipe(debug({ 64 | title: TITLE, 65 | dist: config.dist, 66 | distExt: ".wxs", 67 | })) 68 | .pipe(config.production ? empty() : sourcemaps.init()) 69 | .pipe( 70 | gulpRollup( 71 | { 72 | // rollup: require('rollup'), 73 | onwarn: warn(TITLE), 74 | treeshake: { propertyReadSideEffects: false }, 75 | external: m => m.endsWith(".wxs") && !dependencies.includes(m.split("/")[0]), 76 | plugins: plugins, 77 | // globals:{wx:'wx'} 78 | }, 79 | { 80 | format: "cjs", 81 | esModule: false, 82 | }, 83 | ), 84 | ) 85 | .on("error", error(TITLE)) 86 | .pipe(rename({ extname: ".wxs" })) 87 | .pipe(replace(pkgVar(config.var), undefined, "{{", "}}")) 88 | .pipe(config.production ? empty() : sourcemaps.write()) 89 | .pipe(gulp.dest(config.dist)) 90 | .pipe(size({ title: TITLE, showFiles: true })); 91 | } 92 | module.exports = compileWxts; 93 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | // 加载配置 4 | 5 | var fs = require('fs'); 6 | // var minify = require('node-json-minify'); 7 | var colors = require('ansi-colors'); 8 | var json5 = require('json5'); 9 | 10 | var log = require('./log/logger'); 11 | 12 | var TITLE = colors.gray('config:'); 13 | 14 | var DEFAULT_CONFIG_FILES = [ 15 | 'mpconfig.json', 16 | 'mpconfig.jsonc', 17 | '.mpconfig.json', 18 | '.mpconfig.jsonc', 19 | ] 20 | 21 | const CACHE = {} 22 | 23 | /** 24 | * 读取配置 25 | * @param {string|any} configFile 26 | */ 27 | function loadConfig(configFile) { 28 | if (CACHE[configFile]) { 29 | return CACHE[configFile]; 30 | } 31 | if (configFile) { 32 | if (!fs.existsSync(configFile)) { 33 | log.error(TITLE, colors.red.underline(configFile), colors.bgRed('does not exist')); 34 | throw new Error(configFile + 'does not exist'); 35 | } 36 | } 37 | try { 38 | var json = fs.readFileSync(configFile, 'utf-8'); 39 | var config = json5.parse(json); 40 | // @ts-ignore 41 | const version = require('../package.json').version; 42 | log.info(TITLE, colors.cyan.italic.dim(`v${version}`), colors.gray.dim('load config'), colors.gray.bold.underline(configFile)) 43 | const allowedKeys = Object.keys(exports.default); 44 | 45 | config = Object.keys(config) 46 | .filter(key => allowedKeys.indexOf(key) >= 0) 47 | .reduce((obj, key) => { obj[key] = config[key]; return obj }, {}) 48 | CACHE[configFile] = config; 49 | return config; 50 | } catch (ex) { 51 | log.error(TITLE, colors.red.underline(configFile), 'failed to load.', colors.red(ex)); 52 | // process.exit(1); 53 | throw ex; 54 | } 55 | } 56 | 57 | /** 58 | * 自动读取配置 59 | */ 60 | function autoLoad() { 61 | if (process.argv.indexOf('-c') === -1 && process.argv.indexOf('--config') === -1) { 62 | // 未指定配置时才加载 63 | // try load default configure file 64 | for (var index = 0; index < DEFAULT_CONFIG_FILES.length; index++) { 65 | if (fs.existsSync(DEFAULT_CONFIG_FILES[index])) { 66 | return loadConfig(DEFAULT_CONFIG_FILES[index]); 67 | } 68 | } 69 | } 70 | return {} 71 | }; 72 | /** 73 | * 生成配置文件 74 | * @param {object} conf 75 | * @param {string} [file] 默认 '.mpconfig.jsonc' 76 | */ 77 | function saveConfig(conf, file) { 78 | file = file || '.mpconfig.jsonc'; 79 | if (fs.existsSync(file)) { 80 | log.error(TITLE, colors.red('file (' + file + ') already exists!'), 'Please delete it to regenerate.') 81 | log.error(TITLE, colors.red('配置文件 (' + file + ') 已存在!'), '可删除后重新生成。') 82 | } else { 83 | conf.$schema = 'https://miniprogram-build.newfuture.cc/config.schema.json'; 84 | const str = JSON.stringify(conf, undefined, 4); 85 | fs.writeFileSync(file, str); 86 | log.info(TITLE, colors.green('file `' + file + '` is generated!')) 87 | log.info(TITLE, colors.green('配置文件 `' + file + '` 已生成!')) 88 | } 89 | } 90 | 91 | module.exports.load = loadConfig; 92 | module.exports.save = saveConfig; 93 | module.exports.auto = autoLoad; 94 | 95 | /** 96 | * 全局配置 97 | */ 98 | module.exports.default = { 99 | // debug: true, 100 | production: false, 101 | src: 'src', 102 | dist: 'dist', 103 | assets: 'assets', 104 | exclude: [], 105 | copy: '', 106 | tsconfig: '', 107 | var: { 108 | } 109 | }; -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/merge-media-queries.js: -------------------------------------------------------------------------------- 1 | var canReorder = require('./reorderable').canReorder; 2 | var canReorderSingle = require('./reorderable').canReorderSingle; 3 | var extractProperties = require('./extract-properties'); 4 | var rulesOverlap = require('./rules-overlap'); 5 | 6 | var serializeRules = require('../../writer/one-time').rules; 7 | var OptimizationLevel = require('../../options/optimization-level').OptimizationLevel; 8 | var Token = require('../../tokenizer/token'); 9 | 10 | function mergeMediaQueries(tokens, context) { 11 | var mergeSemantically = context.options.level[OptimizationLevel.Two].mergeSemantically; 12 | var specificityCache = context.cache.specificity; 13 | var candidates = {}; 14 | var reduced = []; 15 | 16 | for (var i = tokens.length - 1; i >= 0; i--) { 17 | var token = tokens[i]; 18 | if (token[0] != Token.NESTED_BLOCK) { 19 | continue; 20 | } 21 | 22 | var key = serializeRules(token[1]); 23 | var candidate = candidates[key]; 24 | if (!candidate) { 25 | candidate = []; 26 | candidates[key] = candidate; 27 | } 28 | 29 | candidate.push(i); 30 | } 31 | 32 | for (var name in candidates) { 33 | var positions = candidates[name]; 34 | 35 | positionLoop: 36 | for (var j = positions.length - 1; j > 0; j--) { 37 | var positionOne = positions[j]; 38 | var tokenOne = tokens[positionOne]; 39 | var positionTwo = positions[j - 1]; 40 | var tokenTwo = tokens[positionTwo]; 41 | 42 | directionLoop: 43 | for (var direction = 1; direction >= -1; direction -= 2) { 44 | var topToBottom = direction == 1; 45 | var from = topToBottom ? positionOne + 1 : positionTwo - 1; 46 | var to = topToBottom ? positionTwo : positionOne; 47 | var delta = topToBottom ? 1 : -1; 48 | var source = topToBottom ? tokenOne : tokenTwo; 49 | var target = topToBottom ? tokenTwo : tokenOne; 50 | var movedProperties = extractProperties(source); 51 | 52 | while (from != to) { 53 | var traversedProperties = extractProperties(tokens[from]); 54 | from += delta; 55 | 56 | if (mergeSemantically && allSameRulePropertiesCanBeReordered(movedProperties, traversedProperties, specificityCache)) { 57 | continue; 58 | } 59 | 60 | if (!canReorder(movedProperties, traversedProperties, specificityCache)) 61 | continue directionLoop; 62 | } 63 | 64 | target[2] = topToBottom ? 65 | source[2].concat(target[2]) : 66 | target[2].concat(source[2]); 67 | source[2] = []; 68 | 69 | reduced.push(target); 70 | continue positionLoop; 71 | } 72 | } 73 | } 74 | 75 | return reduced; 76 | } 77 | 78 | function allSameRulePropertiesCanBeReordered(movedProperties, traversedProperties, specificityCache) { 79 | var movedProperty; 80 | var movedRule; 81 | var traversedProperty; 82 | var traversedRule; 83 | var i, l; 84 | var j, m; 85 | 86 | for (i = 0, l = movedProperties.length; i < l; i++) { 87 | movedProperty = movedProperties[i]; 88 | movedRule = movedProperty[5]; 89 | 90 | for (j = 0, m = traversedProperties.length; j < m; j++) { 91 | traversedProperty = traversedProperties[j]; 92 | traversedRule = traversedProperty[5]; 93 | 94 | if (rulesOverlap(movedRule, traversedRule, true) && !canReorderSingle(movedProperty, traversedProperty, specificityCache)) { 95 | return false; 96 | } 97 | } 98 | } 99 | 100 | return true; 101 | } 102 | 103 | module.exports = mergeMediaQueries; 104 | -------------------------------------------------------------------------------- /test/.svgo.yml: -------------------------------------------------------------------------------- 1 | # replace default config 2 | 3 | # multipass: true 4 | # full: true 5 | 6 | plugins: 7 | # - name 8 | # 9 | # or: 10 | # - name: false 11 | # - name: true 12 | # 13 | # or: 14 | # - name: 15 | # param1: 1 16 | # param2: 2 17 | - addAttributesToSVGElement: false 18 | - addClassesToSVGElement: false 19 | - removeScriptElement: true 20 | - removeStyleElement: true 21 | - removeUselessDefs: true 22 | - cleanupAttrs 23 | - cleanupEnableBackground 24 | - cleanupIDs: 25 | force: true 26 | - cleanupListOfValues 27 | - cleanupNumericValues 28 | - collapseGroups 29 | - convertColors 30 | - convertEllipseToCircle 31 | - convertPathData 32 | - convertShapeToPath 33 | - convertStyleToAttrs 34 | - convertTransform 35 | - inlineStyles: true 36 | - mergePaths: true 37 | - minifyStyles 38 | - moveElemsAttrsToGroup 39 | - moveGroupAttrsToElems 40 | - prefixIds 41 | - removeAttributesBySelector 42 | - removeAttrs: 43 | attrs: 44 | - "data-.*" 45 | - "class" 46 | - removeComments 47 | - removeDesc 48 | - removeDimensions: true 49 | - removeDoctype 50 | - removeEditorsNSData 51 | - removeElementsByAttr 52 | 53 | - removeMetadata 54 | - removeNonInheritableGroupAttrs 55 | - removeOffCanvasPaths: true 56 | - removeRasterImages: true 57 | 58 | - removeTitle 59 | - removeUnknownsAndDefaults 60 | - removeUnusedNS 61 | - removeUselessStrokeAndFill 62 | - removeViewBox 63 | - removeXMLNS 64 | - removeXMLProcInst 65 | 66 | - removeEmptyAttrs 67 | - removeEmptyText 68 | - removeHiddenElems: true 69 | 70 | - removeEmptyContainers: true 71 | - reusePaths: true 72 | 73 | - sortAttrs: true 74 | - sortDefsChildren: true 75 | # - removeDoctype 76 | # - removeXMLProcInst 77 | # - removeComments 78 | # - removeMetadata 79 | # - removeXMLNS: false 80 | # - removeEditorsNSData 81 | # - cleanupAttrs 82 | # - inlineStyles 83 | # - minifyStyles 84 | # - convertStyleToAttrs 85 | # - cleanupIDs 86 | # - prefixIds 87 | # - removeRasterImages 88 | # - removeUselessDefs 89 | # - cleanupNumericValues 90 | # - cleanupListOfValues 91 | # - convertColors 92 | # - removeUnknownsAndDefaults 93 | # - removeNonInheritableGroupAttrs 94 | # - removeUselessStrokeAndFill 95 | # - removeViewBox 96 | # - cleanupEnableBackground 97 | # - removeHiddenElems 98 | # - removeEmptyText 99 | # - convertShapeToPath 100 | # - convertEllipseToCircle 101 | # - moveElemsAttrsToGroup 102 | # - moveGroupAttrsToElems 103 | # - collapseGroups 104 | # - convertPathData 105 | # - convertTransform 106 | # - removeEmptyAttrs 107 | # - removeEmptyContainers 108 | # - mergePaths 109 | # - removeUnusedNS 110 | # - sortAttrs 111 | # - sortDefsChildren 112 | # - removeTitle 113 | # - removeDesc 114 | # - removeDimensions 115 | # - removeAttrs 116 | # - removeAttributesBySelector 117 | # - removeElementsByAttr 118 | # - addClassesToSVGElement 119 | # - removeStyleElement 120 | # - removeScriptElement 121 | # - addAttributesToSVGElement 122 | # - removeOffCanvasPaths 123 | # - reusePaths 124 | # - transformsWithOnePath 125 | 126 | # configure the indent (default 4 spaces) used by `--pretty` here: 127 | # 128 | # @see https://github.com/svg/svgo/blob/master/lib/svgo/js2svg.js#L6 for more config options 129 | # 130 | # js2svg: 131 | # pretty: true 132 | # indent: ' ' 133 | -------------------------------------------------------------------------------- /src/lib/wxss-importer.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | 4 | const path = require('path'); 5 | const fs = require('fs'); 6 | const npm = require('./npm-dependency'); 7 | 8 | /** 9 | * 加载npm 默认导出 scss/css 样式 10 | * @param {string} moduleName 11 | * @returns {string|null} 12 | */ 13 | function importNpmModule(moduleName) { 14 | // 直接引用包名 15 | const modulePath = path.join(process.cwd(), 'node_modules', moduleName); 16 | 17 | // 自动提取 sass/wxss/style 字段 18 | const pkg = npm.loadPackage(modulePath); 19 | const key = [ 20 | 'sass', 21 | 'scss', 22 | // 'wxss', 23 | 'style' 24 | ].find(function (key) { 25 | return typeof pkg[key] === "string"; 26 | }); 27 | if (key || (pkg.main && !pkg.main.endsWith('.js'))) { 28 | // console.log(key, pkg.main, path.join(modulePath, pkg[key || 'main'])); 29 | return path.join(modulePath, pkg[key || 'main']); 30 | } 31 | 32 | // 无有效字段自动搜索 index|style.[scss|sass|wxss|csss] 33 | const name = [ 34 | 'index.scss', 'index.sass', 'index.wxss', 'index.css', 35 | 'style.scss', 'style.sass', 'style.wxss', 'style.css', 36 | ].find(name => fs.existsSync(path.join(modulePath, name))); 37 | if (name) { 38 | return path.join(modulePath, name); 39 | } 40 | 41 | // 尝试搜索 bower.json 42 | const bower = fs.existsSync(path.join(modulePath, 'bower.json')) && npm.loadPackage(modulePath, 'bower.json'); 43 | if (bower) { 44 | const key = ['sass', 'scss', 'wxss', 'css', 'style'].find(key => typeof bower[key] === "string"); 45 | if (key || (bower.main && !bower.main.endsWith('.js'))) { 46 | return path.join(modulePath, bower[key || 'main']) 47 | } 48 | } 49 | } 50 | 51 | /** 52 | * 自动创建scss文件 53 | * @param {string} file 54 | */ 55 | function syncFile(file) { 56 | // console.log(file); 57 | if ( 58 | !['.css', '.scss', '.sass'].includes(path.extname(file)) && 59 | !fs.existsSync(file + '.scss') && 60 | !fs.existsSync(file + '.css') && 61 | !fs.existsSync(file + '.sass') 62 | ) { 63 | fs.copyFileSync(file, file + '.scss'); 64 | } 65 | return file; 66 | 67 | } 68 | 69 | /** 70 | * @param {string} url, 71 | * @param {string} prev, 72 | * @param {function} done, 73 | */ 74 | module.exports = function importer(url, prev, done) { 75 | // console.log('import', url, prev); 76 | if (url[0] === '~' && url[1] !== '/') { 77 | // import from node_modules 78 | const npmModule = url.substr(1); 79 | const n = npmModule.split('/').length; 80 | if (n === 1 || (n === 2 && npmModule[0] === '@')) { 81 | // 直接引用包名 82 | const file = importNpmModule(npmModule); 83 | if (file) { 84 | return { 85 | file: syncFile(file), 86 | } 87 | } 88 | } else { 89 | const file = path.join(process.cwd(), 'node_modules', npmModule); 90 | return { file: syncFile(file) } 91 | } 92 | } else if (prev && prev.indexOf('node_modules') >= 0) { 93 | // inner import of node_modules 94 | // 引用的 node_modules 再次引用其他文件 95 | const file = path.resolve(path.dirname(prev), url); 96 | return { file: syncFile(file) } 97 | } else if (url.endsWith(".wxss") && !fs.existsSync(url + '.scss') && !fs.existsSync(url + '.css') && !fs.existsSync(url + '.sass')) { 98 | // 引用本地wxss 并保持不变 99 | // keep import 100 | // console.log(url); 101 | // dart-sass not support 102 | if (url.startsWith("file://")) { 103 | // fixed dart-sass root file name 104 | url = url.substr(7) 105 | } 106 | return { contents: '@import url("' + url.trim() + '");' }; 107 | 108 | } else { 109 | return null; 110 | } 111 | }; -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/reorderable.js: -------------------------------------------------------------------------------- 1 | // TODO: it'd be great to merge it with the other canReorder functionality 2 | 3 | var rulesOverlap = require('./rules-overlap'); 4 | var specificitiesOverlap = require('./specificities-overlap'); 5 | 6 | var FLEX_PROPERTIES = /align\-items|box\-align|box\-pack|flex|justify/; 7 | var BORDER_PROPERTIES = /^border\-(top|right|bottom|left|color|style|width|radius)/; 8 | 9 | function canReorder(left, right, cache) { 10 | for (var i = right.length - 1; i >= 0; i--) { 11 | for (var j = left.length - 1; j >= 0; j--) { 12 | if (!canReorderSingle(left[j], right[i], cache)) 13 | return false; 14 | } 15 | } 16 | 17 | return true; 18 | } 19 | 20 | function canReorderSingle(left, right, cache) { 21 | var leftName = left[0]; 22 | var leftValue = left[1]; 23 | var leftNameRoot = left[2]; 24 | var leftSelector = left[5]; 25 | var leftInSpecificSelector = left[6]; 26 | var rightName = right[0]; 27 | var rightValue = right[1]; 28 | var rightNameRoot = right[2]; 29 | var rightSelector = right[5]; 30 | var rightInSpecificSelector = right[6]; 31 | 32 | if (leftName == 'font' && rightName == 'line-height' || rightName == 'font' && leftName == 'line-height') 33 | return false; 34 | if (FLEX_PROPERTIES.test(leftName) && FLEX_PROPERTIES.test(rightName)) 35 | return false; 36 | if (leftNameRoot == rightNameRoot && unprefixed(leftName) == unprefixed(rightName) && (vendorPrefixed(leftName) ^ vendorPrefixed(rightName))) 37 | return false; 38 | if (leftNameRoot == 'border' && BORDER_PROPERTIES.test(rightNameRoot) && (leftName == 'border' || leftName == rightNameRoot || (leftValue != rightValue && sameBorderComponent(leftName, rightName)))) 39 | return false; 40 | if (rightNameRoot == 'border' && BORDER_PROPERTIES.test(leftNameRoot) && (rightName == 'border' || rightName == leftNameRoot || (leftValue != rightValue && sameBorderComponent(leftName, rightName)))) 41 | return false; 42 | if (leftNameRoot == 'border' && rightNameRoot == 'border' && leftName != rightName && (isSideBorder(leftName) && isStyleBorder(rightName) || isStyleBorder(leftName) && isSideBorder(rightName))) 43 | return false; 44 | if (leftNameRoot != rightNameRoot) 45 | return true; 46 | if (leftName == rightName && leftNameRoot == rightNameRoot && (leftValue == rightValue || withDifferentVendorPrefix(leftValue, rightValue))) 47 | return true; 48 | if (leftName != rightName && leftNameRoot == rightNameRoot && leftName != leftNameRoot && rightName != rightNameRoot) 49 | return true; 50 | if (leftName != rightName && leftNameRoot == rightNameRoot && leftValue == rightValue) 51 | return true; 52 | if (rightInSpecificSelector && leftInSpecificSelector && !inheritable(leftNameRoot) && !inheritable(rightNameRoot) && !rulesOverlap(rightSelector, leftSelector, false)) 53 | return true; 54 | if (!specificitiesOverlap(leftSelector, rightSelector, cache)) 55 | return true; 56 | 57 | return false; 58 | } 59 | 60 | function vendorPrefixed(name) { 61 | return /^\-(?:moz|webkit|ms|o)\-/.test(name); 62 | } 63 | 64 | function unprefixed(name) { 65 | return name.replace(/^\-(?:moz|webkit|ms|o)\-/, ''); 66 | } 67 | 68 | function sameBorderComponent(name1, name2) { 69 | return name1.split('-').pop() == name2.split('-').pop(); 70 | } 71 | 72 | function isSideBorder(name) { 73 | return name == 'border-top' || name == 'border-right' || name == 'border-bottom' || name == 'border-left'; 74 | } 75 | 76 | function isStyleBorder(name) { 77 | return name == 'border-color' || name == 'border-style' || name == 'border-width'; 78 | } 79 | 80 | function withDifferentVendorPrefix(value1, value2) { 81 | return vendorPrefixed(value1) && vendorPrefixed(value2) && value1.split('-')[1] != value2.split('-')[2]; 82 | } 83 | 84 | function inheritable(name) { 85 | // According to http://www.w3.org/TR/CSS21/propidx.html 86 | // Others will be catched by other, preceeding rules 87 | return name == 'font' || name == 'line-height' || name == 'list-style'; 88 | } 89 | 90 | module.exports = { 91 | canReorder: canReorder, 92 | canReorderSingle: canReorderSingle 93 | }; 94 | -------------------------------------------------------------------------------- /src/task.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | 'use strict'; 3 | 4 | 5 | var gulp = require('gulp'); 6 | var colors = require('ansi-colors'); 7 | var path = require('path'); 8 | 9 | var taskLog = require('./log/task-log'); 10 | var error = require('./log/error'); 11 | var rainbow = require('./log/rainbow'); 12 | 13 | var typescript = require('./tasks/typescript'); 14 | var javascript = require('./tasks/javascript'); 15 | var wxts = require('./tasks/wxts'); 16 | var wxss = require('./tasks/wxss'); 17 | var json = require('./tasks/json'); 18 | var wxml = require('./tasks/wxml'); 19 | var image = require('./tasks/image'); 20 | var npm = require('./tasks/npm'); 21 | var copy = require('./tasks/copy'); 22 | var clean = require('./tasks/clean'); 23 | var devtool = require('./tasks/devtool'); 24 | 25 | const $config = require('./config').default; 26 | devtool.dist = $config.dist; 27 | 28 | exports.$gulp = gulp; 29 | /** 30 | * @param {string[]} tasks 31 | */ 32 | exports.$execute = function (tasks) { 33 | $config.src = path.normalize($config.src); 34 | $config.dist = path.normalize($config.dist); 35 | gulp.series(tasks)(function (err) { 36 | if (err) { 37 | console.error(JSON.stringify(err)); 38 | throw err; 39 | } 40 | }); 41 | } 42 | 43 | // compile 44 | gulp.task('typescript', typescript.build($config)); 45 | gulp.task('javascript', javascript.build($config, ['js'])); 46 | gulp.task('js', gulp.parallel('typescript', 'javascript')); 47 | 48 | gulp.task('wxts', wxts.build($config)); 49 | gulp.task('wxjs', javascript.build($config, ['wxs'])); 50 | gulp.task('wxs', gulp.parallel('wxts', 'wxjs')); 51 | 52 | gulp.task('wxss', wxss.build($config)); 53 | gulp.task('wxml', wxml.build($config)); 54 | gulp.task('json', json.build($config)); 55 | gulp.task('image', image.build($config)); 56 | gulp.task('copy', copy.build($config)); 57 | gulp.task('npm', npm.build($config)); 58 | 59 | //devtool cli 60 | gulp.task('open', devtool.open); 61 | gulp.task('close', devtool.close); 62 | gulp.task('quit', devtool.quit); 63 | gulp.task('upload', devtool.upload); 64 | gulp.task('auto-preview', devtool.autopreview) 65 | gulp.task('autopreview', devtool.autopreview) 66 | gulp.task('try-open', devtool.tryOpen) 67 | gulp.task('try-quit', devtool.tryQuit) 68 | 69 | 70 | // watch 71 | gulp.task('typescript-watch', typescript.watch($config)); 72 | gulp.task('javascript-watch', javascript.watch($config, ['js'])); 73 | gulp.task('js-watch', gulp.parallel('typescript-watch', 'javascript-watch')); 74 | 75 | gulp.task('wxts-watch', wxts.watch($config)); 76 | gulp.task('wxjs-watch', javascript.watch($config, ['wxs'])); 77 | gulp.task('wxs-watch', gulp.parallel('wxts-watch', 'wxjs-watch')); 78 | 79 | gulp.task('wxss-watch', wxss.watch($config)); 80 | gulp.task('wxml-watch', wxml.watch($config)); 81 | gulp.task('json-watch', json.watch($config)); 82 | gulp.task('image-watch', image.watch($config)); 83 | gulp.task('copy-watch', copy.watch($config)); 84 | gulp.task('npm-watch', npm.watch($config)); 85 | 86 | gulp.task('clean', clean.build($config)); 87 | 88 | //编译项目 89 | gulp.task('compile', gulp.series( 90 | taskLog(rainbow("↓↓↓↓↓↓"), 'start compile:', colors.cyan.bold.underline($config.src), '→', colors.green.bold.underline($config.dist), rainbow("↓↓↓↓↓↓")), 91 | gulp.parallel('js', 'wxs', 'wxss', 'wxml', 'json', 'image', 'copy', 'npm'), 92 | taskLog(rainbow("↑↑↑↑↑↑"), colors.greenBright.bold(colors.symbols.check + ' All compilation tasks done!'), rainbow("↑↑↑↑↑↑")) 93 | )) 94 | // 重新生成文件 95 | gulp.task('build', gulp.series('clean', 'compile')); 96 | // 监测文件修改 97 | gulp.task('watch', gulp.series( 98 | gulp.parallel('js-watch', 'wxs-watch', 'wxss-watch', 'wxml-watch', 'json-watch', 'image-watch', 'copy-watch', 'npm-watch'), 99 | taskLog(colors.greenBright.bold('\tAll watch tasks started !'))), 100 | ); 101 | 102 | //开发模式 103 | gulp.task('dev', gulp.series( 104 | // 'try-quit', 105 | 'clean', 'compile', 106 | gulp.parallel('try-open', 'watch'), 107 | taskLog(colors.inverse(rainbow('all tasks are ready, waiting for code change ...'))), 108 | )); 109 | 110 | gulp.on('error', console.trace); 111 | gulp.on('error', error('gulp')); 112 | -------------------------------------------------------------------------------- /vendor/clean-css/reader/load-original-sources.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | 4 | var isAllowedResource = require('./is-allowed-resource'); 5 | 6 | var hasProtocol = require('../utils/has-protocol'); 7 | var isRemoteResource = require('../utils/is-remote-resource'); 8 | 9 | function loadOriginalSources(context, callback) { 10 | var loadContext = { 11 | callback: callback, 12 | fetch: context.options.fetch, 13 | index: 0, 14 | inline: context.options.inline, 15 | inlineRequest: context.options.inlineRequest, 16 | inlineTimeout: context.options.inlineTimeout, 17 | localOnly: context.localOnly, 18 | rebaseTo: context.options.rebaseTo, 19 | sourcesContent: context.sourcesContent, 20 | uriToSource: uriToSourceMapping(context.inputSourceMapTracker.all()), 21 | warnings: context.warnings 22 | }; 23 | 24 | return context.options.sourceMap && context.options.sourceMapInlineSources ? 25 | doLoadOriginalSources(loadContext) : 26 | callback(); 27 | } 28 | 29 | function uriToSourceMapping(allSourceMapConsumers) { 30 | var mapping = {}; 31 | var consumer; 32 | var uri; 33 | var source; 34 | var i, l; 35 | 36 | for (source in allSourceMapConsumers) { 37 | consumer = allSourceMapConsumers[source]; 38 | 39 | for (i = 0, l = consumer.sources.length; i < l; i++) { 40 | uri = consumer.sources[i]; 41 | source = consumer.sourceContentFor(uri, true); 42 | 43 | mapping[uri] = source; 44 | } 45 | } 46 | 47 | return mapping; 48 | } 49 | 50 | function doLoadOriginalSources(loadContext) { 51 | var uris = Object.keys(loadContext.uriToSource); 52 | var uri; 53 | var source; 54 | var total; 55 | 56 | for (total = uris.length; loadContext.index < total; loadContext.index++) { 57 | uri = uris[loadContext.index]; 58 | source = loadContext.uriToSource[uri]; 59 | 60 | if (source) { 61 | loadContext.sourcesContent[uri] = source; 62 | } else { 63 | return loadOriginalSource(uri, loadContext); 64 | } 65 | } 66 | 67 | return loadContext.callback(); 68 | } 69 | 70 | function loadOriginalSource(uri, loadContext) { 71 | var content; 72 | 73 | if (isRemoteResource(uri)) { 74 | return loadOriginalSourceFromRemoteUri(uri, loadContext, function (content) { 75 | loadContext.index++; 76 | loadContext.sourcesContent[uri] = content; 77 | return doLoadOriginalSources(loadContext); 78 | }); 79 | } else { 80 | content = loadOriginalSourceFromLocalUri(uri, loadContext); 81 | loadContext.index++; 82 | loadContext.sourcesContent[uri] = content; 83 | return doLoadOriginalSources(loadContext); 84 | } 85 | } 86 | 87 | function loadOriginalSourceFromRemoteUri(uri, loadContext, whenLoaded) { 88 | var isAllowed = isAllowedResource(uri, true, loadContext.inline); 89 | var isRuntimeResource = !hasProtocol(uri); 90 | 91 | if (loadContext.localOnly) { 92 | loadContext.warnings.push('Cannot fetch remote resource from "' + uri + '" as no callback given.'); 93 | return whenLoaded(null); 94 | } else if (isRuntimeResource) { 95 | loadContext.warnings.push('Cannot fetch "' + uri + '" as no protocol given.'); 96 | return whenLoaded(null); 97 | } else if (!isAllowed) { 98 | loadContext.warnings.push('Cannot fetch "' + uri + '" as resource is not allowed.'); 99 | return whenLoaded(null); 100 | } 101 | 102 | loadContext.fetch(uri, loadContext.inlineRequest, loadContext.inlineTimeout, function (error, content) { 103 | if (error) { 104 | loadContext.warnings.push('Missing original source at "' + uri + '" - ' + error); 105 | } 106 | 107 | whenLoaded(content); 108 | }); 109 | } 110 | 111 | function loadOriginalSourceFromLocalUri(relativeUri, loadContext) { 112 | var isAllowed = isAllowedResource(relativeUri, false, loadContext.inline); 113 | var absoluteUri = path.resolve(loadContext.rebaseTo, relativeUri); 114 | 115 | if (!fs.existsSync(absoluteUri) || !fs.statSync(absoluteUri).isFile()) { 116 | loadContext.warnings.push('Ignoring local source map at "' + absoluteUri + '" as resource is missing.'); 117 | return null; 118 | } else if (!isAllowed) { 119 | loadContext.warnings.push('Cannot fetch "' + absoluteUri + '" as resource is not allowed.'); 120 | return null; 121 | } 122 | 123 | return fs.readFileSync(absoluteUri, 'utf8'); 124 | } 125 | 126 | module.exports = loadOriginalSources; 127 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-2/optimize.js: -------------------------------------------------------------------------------- 1 | var mergeAdjacent = require('./merge-adjacent'); 2 | var mergeMediaQueries = require('./merge-media-queries'); 3 | var mergeNonAdjacentByBody = require('./merge-non-adjacent-by-body'); 4 | var mergeNonAdjacentBySelector = require('./merge-non-adjacent-by-selector'); 5 | var reduceNonAdjacent = require('./reduce-non-adjacent'); 6 | var removeDuplicateFontAtRules = require('./remove-duplicate-font-at-rules'); 7 | var removeDuplicateMediaQueries = require('./remove-duplicate-media-queries'); 8 | var removeDuplicates = require('./remove-duplicates'); 9 | var removeUnusedAtRules = require('./remove-unused-at-rules'); 10 | var restructure = require('./restructure'); 11 | 12 | var optimizeProperties = require('./properties/optimize'); 13 | 14 | var OptimizationLevel = require('../../options/optimization-level').OptimizationLevel; 15 | 16 | var Token = require('../../tokenizer/token'); 17 | 18 | function removeEmpty(tokens) { 19 | for (var i = 0, l = tokens.length; i < l; i++) { 20 | var token = tokens[i]; 21 | var isEmpty = false; 22 | 23 | switch (token[0]) { 24 | case Token.RULE: 25 | isEmpty = token[1].length === 0 || token[2].length === 0; 26 | break; 27 | case Token.NESTED_BLOCK: 28 | removeEmpty(token[2]); 29 | isEmpty = token[2].length === 0; 30 | break; 31 | case Token.AT_RULE: 32 | isEmpty = token[1].length === 0; 33 | break; 34 | case Token.AT_RULE_BLOCK: 35 | isEmpty = token[2].length === 0; 36 | } 37 | 38 | if (isEmpty) { 39 | tokens.splice(i, 1); 40 | i--; 41 | l--; 42 | } 43 | } 44 | } 45 | 46 | function recursivelyOptimizeBlocks(tokens, context) { 47 | for (var i = 0, l = tokens.length; i < l; i++) { 48 | var token = tokens[i]; 49 | 50 | if (token[0] == Token.NESTED_BLOCK) { 51 | var isKeyframes = /@(-moz-|-o-|-webkit-)?keyframes/.test(token[1][0][1]); 52 | level2Optimize(token[2], context, !isKeyframes); 53 | } 54 | } 55 | } 56 | 57 | function recursivelyOptimizeProperties(tokens, context) { 58 | for (var i = 0, l = tokens.length; i < l; i++) { 59 | var token = tokens[i]; 60 | 61 | switch (token[0]) { 62 | case Token.RULE: 63 | optimizeProperties(token[2], true, true, context); 64 | break; 65 | case Token.NESTED_BLOCK: 66 | recursivelyOptimizeProperties(token[2], context); 67 | } 68 | } 69 | } 70 | 71 | function level2Optimize(tokens, context, withRestructuring) { 72 | var levelOptions = context.options.level[OptimizationLevel.Two]; 73 | var reduced; 74 | var i; 75 | 76 | recursivelyOptimizeBlocks(tokens, context); 77 | recursivelyOptimizeProperties(tokens, context); 78 | 79 | if (levelOptions.removeDuplicateRules) { 80 | removeDuplicates(tokens, context); 81 | } 82 | 83 | if (levelOptions.mergeAdjacentRules) { 84 | mergeAdjacent(tokens, context); 85 | } 86 | 87 | if (levelOptions.reduceNonAdjacentRules) { 88 | reduceNonAdjacent(tokens, context); 89 | } 90 | 91 | if (levelOptions.mergeNonAdjacentRules && levelOptions.mergeNonAdjacentRules != 'body') { 92 | mergeNonAdjacentBySelector(tokens, context); 93 | } 94 | 95 | if (levelOptions.mergeNonAdjacentRules && levelOptions.mergeNonAdjacentRules != 'selector') { 96 | mergeNonAdjacentByBody(tokens, context); 97 | } 98 | 99 | if (levelOptions.restructureRules && levelOptions.mergeAdjacentRules && withRestructuring) { 100 | restructure(tokens, context); 101 | mergeAdjacent(tokens, context); 102 | } 103 | 104 | if (levelOptions.restructureRules && !levelOptions.mergeAdjacentRules && withRestructuring) { 105 | restructure(tokens, context); 106 | } 107 | 108 | if (levelOptions.removeDuplicateFontRules) { 109 | removeDuplicateFontAtRules(tokens, context); 110 | } 111 | 112 | if (levelOptions.removeDuplicateMediaBlocks) { 113 | removeDuplicateMediaQueries(tokens, context); 114 | } 115 | 116 | if (levelOptions.removeUnusedAtRules) { 117 | removeUnusedAtRules(tokens, context); 118 | } 119 | 120 | if (levelOptions.mergeMedia) { 121 | reduced = mergeMediaQueries(tokens, context); 122 | for (i = reduced.length - 1; i >= 0; i--) { 123 | level2Optimize(reduced[i][2], context, false); 124 | } 125 | } 126 | 127 | if (levelOptions.removeEmpty) { 128 | removeEmpty(tokens); 129 | } 130 | 131 | return tokens; 132 | } 133 | 134 | module.exports = level2Optimize; 135 | -------------------------------------------------------------------------------- /src/lib/image-min.js: -------------------------------------------------------------------------------- 1 | 2 | ///@ts-check 3 | "use strict"; 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | const through = require('through2'); 7 | const PluginError = require('../lib/error'); 8 | const prettyBytes = require('./pretty-bytes'); 9 | const chalk = require('ansi-colors'); 10 | const imagemin = require('imagemin'); 11 | const log = require('../log/logger'); 12 | const color = require('../log/color'); 13 | 14 | const PLUGIN_NAME = 'image'; 15 | const defaultPlugins = ['gifsicle', 'jpegtran', 'optipng', 'svgo']; 16 | 17 | function loadDefaultSvgoConfig() { 18 | const yaml = require('js-yaml'); 19 | const FILE = '.svgo.yml'; 20 | if (fs.existsSync(FILE)) { 21 | return yaml.safeLoad(fs.readFileSync(FILE, 'utf8')); 22 | } 23 | return undefined 24 | } 25 | const loadPlugin = (plugin, ...args) => { 26 | try { 27 | const pluginModule = require(`imagemin-${plugin}`); 28 | var svgconfig; 29 | if (plugin === "svgo" && (svgconfig = loadDefaultSvgoConfig())) { 30 | const config = args[0] || {}; 31 | const svgplugins = svgconfig.plugins || []; 32 | return pluginModule(Object.assign({}, svgconfig, config, { 33 | plugins: svgplugins.concat(config.plugins || []) 34 | })) 35 | } 36 | return pluginModule(...args); 37 | 38 | } catch (error) { 39 | log.error(`${PLUGIN_NAME}: Couldn't load default plugin "${plugin}"`); 40 | } 41 | }; 42 | 43 | const exposePlugin = plugin => (...args) => loadPlugin(plugin, ...args); 44 | 45 | const getDefaultPlugins = () => 46 | defaultPlugins.reduce((plugins, plugin) => { 47 | const instance = loadPlugin(plugin); 48 | 49 | if (!instance) { 50 | return plugins; 51 | } 52 | 53 | return plugins.concat(instance); 54 | }, []); 55 | 56 | 57 | module.exports = (plugins, options) => { 58 | if (typeof plugins === 'object' && !Array.isArray(plugins)) { 59 | options = plugins; 60 | plugins = null; 61 | } 62 | 63 | options = Object.assign({ 64 | // TODO: Remove this when Gulp gets a real logger with levels 65 | verbose: process.argv.includes('--verbose') 66 | }, options); 67 | 68 | const validExts = ['.jpg', '.jpeg', '.png', '.gif', '.svg']; 69 | 70 | let totalBytes = 0; 71 | let totalSavedBytes = 0; 72 | 73 | return through.obj( 74 | // { 75 | // maxConcurrency: 8 76 | // }, 77 | (file, enc, cb) => { 78 | if (file.isNull()) { 79 | cb(null, file); 80 | return; 81 | } 82 | 83 | if (file.isStream()) { 84 | cb(new PluginError(PLUGIN_NAME, 'Streaming not supported')); 85 | return; 86 | } 87 | 88 | if (!validExts.includes(path.extname(file.path).toLowerCase())) { 89 | if (options.verbose) { 90 | log(`${PLUGIN_NAME}: Skipping unsupported image ${chalk.blue(file.relative)}`); 91 | } 92 | 93 | cb(null, file); 94 | return; 95 | } 96 | 97 | const use = plugins || getDefaultPlugins(); 98 | 99 | imagemin.buffer(file.contents, { plugins: use }) 100 | .then(data => { 101 | const originalSize = file.contents.length; 102 | const optimizedSize = data.length; 103 | const saved = originalSize - optimizedSize; 104 | const percent = originalSize > 0 ? (saved / originalSize) * 100 : 0; 105 | const savedMsg = `saved ${prettyBytes(saved)} - ${percent.toFixed(1).replace(/\.0$/, '')}%`; 106 | const msg = saved > 0 ? savedMsg : 'already optimized'; 107 | 108 | if (saved > 0) { 109 | totalBytes += originalSize; 110 | totalSavedBytes += saved; 111 | } 112 | 113 | if (options.verbose) { 114 | log(color(`${PLUGIN_NAME}`), chalk.symbols.check, chalk.underline(file.relative), chalk.gray(` (${msg})`)); 115 | } 116 | 117 | file.contents = data; 118 | cb(null, file); 119 | }) 120 | .catch(error => { 121 | cb(new PluginError(PLUGIN_NAME, error, { fileName: file.path })); 122 | }); 123 | }, cb => { 124 | this.percent = totalBytes > 0 ? (totalSavedBytes / totalBytes) * 100 : 0; 125 | // let msg = `Minified ${totalFiles} ${plur('image', totalFiles)}`; 126 | 127 | // if (totalFiles > 0) { 128 | // msg += chalk.gray(` (saved ${prettyBytes(totalSavedBytes)} - ${percent.toFixed(1).replace(/\.0$/, '')}%)`); 129 | // } 130 | 131 | // log(`${PLUGIN_NAME}:`, msg); 132 | cb(); 133 | }); 134 | }; 135 | 136 | module.exports.getDefaultPlugins = getDefaultPlugins; 137 | module.exports.gifsicle = exposePlugin('gifsicle'); 138 | module.exports.jpegtran = exposePlugin('jpegtran'); 139 | module.exports.optipng = exposePlugin('optipng'); 140 | module.exports.svgo = exposePlugin('svgo'); 141 | -------------------------------------------------------------------------------- /src/compiler/build-npm.js: -------------------------------------------------------------------------------- 1 | ///@ts-check 2 | "use strict"; 3 | 4 | const fs = require("fs"); 5 | const path = require("path"); 6 | 7 | const gulp = require("gulp"); 8 | const gulpRename = require("gulp-rename"); 9 | 10 | // const gulpRollup = require("gulp-better-rollup"); 11 | const npm = require("../lib/npm-dependency"); 12 | const loadPlugins = require("../lib/rollup-plugins"); 13 | const error = require("../log/error"); 14 | const warn = require("../log/warn"); 15 | const debug = require("../log/compile"); 16 | const size = require("../log/size"); 17 | 18 | const TITLE = "npm"; 19 | 20 | /** 21 | * 组件component 22 | * @param {string} dependencyName 23 | * @param {string} mpSrcPath 24 | * @param {string} destName 25 | */ 26 | function createMpTask(dependencyName, mpSrcPath, destName) { 27 | return () => { 28 | return gulp 29 | .src(path.join(mpSrcPath, "**/*")) 30 | .pipe( 31 | debug({ 32 | title: TITLE, 33 | srcName: `<${dependencyName}(component)>`, 34 | dist: path.join(destName, "miniprogram_npm", dependencyName) + path.sep, 35 | // distName: destName 36 | // once: true, 37 | }), 38 | ) 39 | .pipe(gulp.dest(destName)) 40 | .on("error", error(`${TITLE} <${dependencyName}(component)>`)) 41 | .pipe( 42 | size({ 43 | title: TITLE, 44 | sub: `${dependencyName}(component)`, 45 | showFiles: false, 46 | showTotal: true, 47 | }), 48 | ); 49 | }; 50 | } 51 | 52 | /** 53 | * 普通NPM依赖 rollup 54 | * @param {string} dependencyName 55 | * @param {string} entryFilePath 56 | * @param {string} destName 57 | * @param {string[]} dependencyNames 58 | */ 59 | function createNpmTask(dependencyName, entryFilePath, destName, dependencyNames) { 60 | const gulpRollup = require("gulp-better-rollup"); 61 | const rollup = require("rollup"); 62 | if (!fs.existsSync(entryFilePath)) { 63 | warn(TITLE)(`can't resolve ${entryFilePath}`); 64 | return (cb) => { 65 | cb(); 66 | } 67 | } 68 | return () => 69 | gulp 70 | .src(entryFilePath) 71 | .pipe( 72 | debug({ 73 | title: TITLE, 74 | srcName: `<${dependencyName}>`, 75 | dist: path.join(destName, "miniprogram_npm", dependencyName), 76 | // distName: destName 77 | }), 78 | ) 79 | .pipe( 80 | gulpRollup( 81 | { 82 | rollup: rollup, 83 | onwarn: warn(TITLE, dependencyName), 84 | external: dependencyNames, 85 | treeshake: { propertyReadSideEffects: false }, 86 | plugins: loadPlugins(), 87 | }, 88 | { 89 | format: "es", 90 | esModule: false, 91 | } 92 | ), 93 | ) 94 | .on("error", error(`${TITLE} <${dependencyName}>`)) 95 | .pipe( 96 | gulpRename({ 97 | basename: "index", 98 | extname: ".js", 99 | }), 100 | ) 101 | .pipe(gulp.dest(destName)) 102 | .pipe(size({ title: TITLE, sub: dependencyName, showFiles: false, showTotal: true })); 103 | } 104 | 105 | module.exports = 106 | /** 107 | * 108 | * @param {string} cwd 109 | * @param {string} distPath 110 | * @param {string[]} baseDependencies 111 | */ 112 | function buildNpm(cwd, distPath, baseDependencies) { 113 | const mp_npm = npm.getMp_NpmDependencies(baseDependencies, cwd, cwd); 114 | const mpDependencies = mp_npm[0]; 115 | const npmDependencies = mp_npm[1]; 116 | const mpTask = Object.keys(mpDependencies).reduce((result, depName) => { 117 | const mpDistPath = mpDependencies[depName]; 118 | const dest = path.join(distPath, "miniprogram_npm", depName); 119 | result.push(createMpTask(depName, mpDistPath, dest)); 120 | return result 121 | }, []); 122 | 123 | const dependencyNames = Object.keys(npmDependencies); 124 | const npmTasks = dependencyNames.reduce((result, dependencyName) => { 125 | const entryFilePath = npmDependencies[dependencyName]; 126 | const dest = path.join(distPath, "miniprogram_npm", dependencyName); 127 | result.push(createNpmTask(dependencyName, entryFilePath, dest, dependencyNames)); 128 | return result; 129 | }, []); 130 | return gulp.parallel(mpTask.concat(npmTasks)); 131 | }; 132 | -------------------------------------------------------------------------------- /test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ 5 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 6 | "lib": ["es5"], /* Specify library files to be included in the compilation. */ 7 | // "allowJs": true, /* Allow javascript files to be compiled. */ 8 | // "checkJs": true, /* Report errors in .js files. */ 9 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 10 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 11 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 12 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 13 | // "outFile": "./", /* Concatenate and emit output to single file. */ 14 | "outDir": "dist", /* Redirect output structure to the directory. */ 15 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 16 | // "composite": true, /* Enable project compilation */ 17 | // "removeComments": true, /* Do not emit comments to output. */ 18 | // "noEmit": true, /* Do not emit outputs. */ 19 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 20 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 21 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 22 | /* Strict Type-Checking Options */ 23 | "strict": true, /* Enable all strict type-checking options. */ 24 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 25 | // "strictNullChecks": true, /* Enable strict null checks. */ 26 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 27 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 28 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 29 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 30 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 31 | /* Additional Checks */ 32 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 33 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 34 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 35 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 36 | /* Module Resolution Options */ 37 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 38 | "baseUrl": "./src", /* Base directory to resolve non-absolute module names. */ 39 | "paths": { 40 | "/*": [ 41 | "./*" 42 | ] 43 | }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 44 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 45 | "types": [ 46 | "@dragongate/miniprogram-api-typings", 47 | ], 48 | // "types": [], /* Type declaration files to be included in compilation. */ 49 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 50 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 51 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 52 | /* Source Map Options */ 53 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 54 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 55 | "inlineSourceMap": true /* Emit a single file with source maps instead of having a separate file. */ 56 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 57 | /* Experimental Options */ 58 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 59 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 60 | } 61 | } -------------------------------------------------------------------------------- /vendor/clean-css/options/compatibility.js: -------------------------------------------------------------------------------- 1 | var DEFAULTS = { 2 | '*': { 3 | colors: { 4 | opacity: true // rgba / hsla 5 | }, 6 | properties: { 7 | backgroundClipMerging: true, // background-clip to shorthand 8 | backgroundOriginMerging: true, // background-origin to shorthand 9 | backgroundSizeMerging: true, // background-size to shorthand 10 | colors: true, // any kind of color transformations, like `#ff00ff` to `#f0f` or `#fff` into `red` 11 | ieBangHack: false, // !ie suffix hacks on IE<8 12 | ieFilters: false, // whether to preserve `filter` and `-ms-filter` properties 13 | iePrefixHack: false, // underscore / asterisk prefix hacks on IE 14 | ieSuffixHack: false, // \9 suffix hacks on IE6-9 15 | merging: true, // merging properties into one 16 | shorterLengthUnits: false, // optimize pixel units into `pt`, `pc` or `in` units 17 | spaceAfterClosingBrace: true, // 'url() no-repeat' to 'url()no-repeat' 18 | urlQuotes: false, // whether to wrap content of `url()` into quotes or not 19 | zeroUnits: true // 0[unit] -> 0 20 | }, 21 | selectors: { 22 | adjacentSpace: false, // div+ nav Android stock browser hack 23 | ie7Hack: false, // *+html hack 24 | mergeablePseudoClasses: [ 25 | ':active', 26 | ':after', 27 | ':before', 28 | ':empty', 29 | ':checked', 30 | ':disabled', 31 | ':empty', 32 | ':enabled', 33 | ':first-child', 34 | ':first-letter', 35 | ':first-line', 36 | ':first-of-type', 37 | ':focus', 38 | ':hover', 39 | ':lang', 40 | ':last-child', 41 | ':last-of-type', 42 | ':link', 43 | ':not', 44 | ':nth-child', 45 | ':nth-last-child', 46 | ':nth-last-of-type', 47 | ':nth-of-type', 48 | ':only-child', 49 | ':only-of-type', 50 | ':root', 51 | ':target', 52 | ':visited' 53 | ], // selectors with these pseudo-classes can be merged as these are universally supported 54 | mergeablePseudoElements: [ 55 | '::after', 56 | '::before', 57 | '::first-letter', 58 | '::first-line' 59 | ], // selectors with these pseudo-elements can be merged as these are universally supported 60 | mergeLimit: 8191, // number of rules that can be safely merged together 61 | multiplePseudoMerging: true 62 | }, 63 | units: { 64 | ch: true, 65 | in: true, 66 | pc: true, 67 | pt: true, 68 | rem: true, 69 | vh: true, 70 | vm: true, // vm is vmin on IE9+ see https://developer.mozilla.org/en-US/docs/Web/CSS/length 71 | vmax: true, 72 | vmin: true, 73 | vw: true 74 | } 75 | } 76 | }; 77 | 78 | DEFAULTS.ie11 = DEFAULTS['*']; 79 | 80 | DEFAULTS.ie10 = DEFAULTS['*']; 81 | 82 | DEFAULTS.ie9 = merge(DEFAULTS['*'], { 83 | properties: { 84 | ieFilters: true, 85 | ieSuffixHack: true 86 | } 87 | }); 88 | 89 | DEFAULTS.ie8 = merge(DEFAULTS.ie9, { 90 | colors: { 91 | opacity: false 92 | }, 93 | properties: { 94 | backgroundClipMerging: false, 95 | backgroundOriginMerging: false, 96 | backgroundSizeMerging: false, 97 | iePrefixHack: true, 98 | merging: false 99 | }, 100 | selectors: { 101 | mergeablePseudoClasses: [ 102 | ':after', 103 | ':before', 104 | ':first-child', 105 | ':first-letter', 106 | ':focus', 107 | ':hover', 108 | ':visited' 109 | ], 110 | mergeablePseudoElements: [] 111 | }, 112 | units: { 113 | ch: false, 114 | rem: false, 115 | vh: false, 116 | vm: false, 117 | vmax: false, 118 | vmin: false, 119 | vw: false 120 | } 121 | }); 122 | 123 | DEFAULTS.ie7 = merge(DEFAULTS.ie8, { 124 | properties: { 125 | ieBangHack: true 126 | }, 127 | selectors: { 128 | ie7Hack: true, 129 | mergeablePseudoClasses: [ 130 | ':first-child', 131 | ':first-letter', 132 | ':hover', 133 | ':visited' 134 | ] 135 | }, 136 | }); 137 | 138 | function compatibilityFrom(source) { 139 | return merge(DEFAULTS['*'], calculateSource(source)); 140 | } 141 | 142 | function merge(source, target) { 143 | for (var key in source) { 144 | var value = source[key]; 145 | 146 | if (typeof value === 'object' && !Array.isArray(value)) { 147 | target[key] = merge(value, target[key] || {}); 148 | } else { 149 | target[key] = key in target ? target[key] : value; 150 | } 151 | } 152 | 153 | return target; 154 | } 155 | 156 | function calculateSource(source) { 157 | if (typeof source == 'object') 158 | return source; 159 | 160 | if (!/[,\+\-]/.test(source)) 161 | return DEFAULTS[source] || DEFAULTS['*']; 162 | 163 | var parts = source.split(','); 164 | var template = parts[0] in DEFAULTS ? 165 | DEFAULTS[parts.shift()] : 166 | DEFAULTS['*']; 167 | 168 | source = {}; 169 | 170 | parts.forEach(function (part) { 171 | var isAdd = part[0] == '+'; 172 | var key = part.substring(1).split('.'); 173 | var group = key[0]; 174 | var option = key[1]; 175 | 176 | source[group] = source[group] || {}; 177 | source[group][option] = isAdd; 178 | }); 179 | 180 | return merge(template, source); 181 | } 182 | 183 | module.exports = compatibilityFrom; 184 | -------------------------------------------------------------------------------- /vendor/clean-css/optimizer/level-1/shorten-hex.js: -------------------------------------------------------------------------------- 1 | var COLORS = { 2 | aliceblue: '#f0f8ff', 3 | antiquewhite: '#faebd7', 4 | aqua: '#0ff', 5 | aquamarine: '#7fffd4', 6 | azure: '#f0ffff', 7 | beige: '#f5f5dc', 8 | bisque: '#ffe4c4', 9 | black: '#000', 10 | blanchedalmond: '#ffebcd', 11 | blue: '#00f', 12 | blueviolet: '#8a2be2', 13 | brown: '#a52a2a', 14 | burlywood: '#deb887', 15 | cadetblue: '#5f9ea0', 16 | chartreuse: '#7fff00', 17 | chocolate: '#d2691e', 18 | coral: '#ff7f50', 19 | cornflowerblue: '#6495ed', 20 | cornsilk: '#fff8dc', 21 | crimson: '#dc143c', 22 | cyan: '#0ff', 23 | darkblue: '#00008b', 24 | darkcyan: '#008b8b', 25 | darkgoldenrod: '#b8860b', 26 | darkgray: '#a9a9a9', 27 | darkgreen: '#006400', 28 | darkgrey: '#a9a9a9', 29 | darkkhaki: '#bdb76b', 30 | darkmagenta: '#8b008b', 31 | darkolivegreen: '#556b2f', 32 | darkorange: '#ff8c00', 33 | darkorchid: '#9932cc', 34 | darkred: '#8b0000', 35 | darksalmon: '#e9967a', 36 | darkseagreen: '#8fbc8f', 37 | darkslateblue: '#483d8b', 38 | darkslategray: '#2f4f4f', 39 | darkslategrey: '#2f4f4f', 40 | darkturquoise: '#00ced1', 41 | darkviolet: '#9400d3', 42 | deeppink: '#ff1493', 43 | deepskyblue: '#00bfff', 44 | dimgray: '#696969', 45 | dimgrey: '#696969', 46 | dodgerblue: '#1e90ff', 47 | firebrick: '#b22222', 48 | floralwhite: '#fffaf0', 49 | forestgreen: '#228b22', 50 | fuchsia: '#f0f', 51 | gainsboro: '#dcdcdc', 52 | ghostwhite: '#f8f8ff', 53 | gold: '#ffd700', 54 | goldenrod: '#daa520', 55 | gray: '#808080', 56 | green: '#008000', 57 | greenyellow: '#adff2f', 58 | grey: '#808080', 59 | honeydew: '#f0fff0', 60 | hotpink: '#ff69b4', 61 | indianred: '#cd5c5c', 62 | indigo: '#4b0082', 63 | ivory: '#fffff0', 64 | khaki: '#f0e68c', 65 | lavender: '#e6e6fa', 66 | lavenderblush: '#fff0f5', 67 | lawngreen: '#7cfc00', 68 | lemonchiffon: '#fffacd', 69 | lightblue: '#add8e6', 70 | lightcoral: '#f08080', 71 | lightcyan: '#e0ffff', 72 | lightgoldenrodyellow: '#fafad2', 73 | lightgray: '#d3d3d3', 74 | lightgreen: '#90ee90', 75 | lightgrey: '#d3d3d3', 76 | lightpink: '#ffb6c1', 77 | lightsalmon: '#ffa07a', 78 | lightseagreen: '#20b2aa', 79 | lightskyblue: '#87cefa', 80 | lightslategray: '#778899', 81 | lightslategrey: '#778899', 82 | lightsteelblue: '#b0c4de', 83 | lightyellow: '#ffffe0', 84 | lime: '#0f0', 85 | limegreen: '#32cd32', 86 | linen: '#faf0e6', 87 | magenta: '#ff00ff', 88 | maroon: '#800000', 89 | mediumaquamarine: '#66cdaa', 90 | mediumblue: '#0000cd', 91 | mediumorchid: '#ba55d3', 92 | mediumpurple: '#9370db', 93 | mediumseagreen: '#3cb371', 94 | mediumslateblue: '#7b68ee', 95 | mediumspringgreen: '#00fa9a', 96 | mediumturquoise: '#48d1cc', 97 | mediumvioletred: '#c71585', 98 | midnightblue: '#191970', 99 | mintcream: '#f5fffa', 100 | mistyrose: '#ffe4e1', 101 | moccasin: '#ffe4b5', 102 | navajowhite: '#ffdead', 103 | navy: '#000080', 104 | oldlace: '#fdf5e6', 105 | olive: '#808000', 106 | olivedrab: '#6b8e23', 107 | orange: '#ffa500', 108 | orangered: '#ff4500', 109 | orchid: '#da70d6', 110 | palegoldenrod: '#eee8aa', 111 | palegreen: '#98fb98', 112 | paleturquoise: '#afeeee', 113 | palevioletred: '#db7093', 114 | papayawhip: '#ffefd5', 115 | peachpuff: '#ffdab9', 116 | peru: '#cd853f', 117 | pink: '#ffc0cb', 118 | plum: '#dda0dd', 119 | powderblue: '#b0e0e6', 120 | purple: '#800080', 121 | rebeccapurple: '#663399', 122 | red: '#f00', 123 | rosybrown: '#bc8f8f', 124 | royalblue: '#4169e1', 125 | saddlebrown: '#8b4513', 126 | salmon: '#fa8072', 127 | sandybrown: '#f4a460', 128 | seagreen: '#2e8b57', 129 | seashell: '#fff5ee', 130 | sienna: '#a0522d', 131 | silver: '#c0c0c0', 132 | skyblue: '#87ceeb', 133 | slateblue: '#6a5acd', 134 | slategray: '#708090', 135 | slategrey: '#708090', 136 | snow: '#fffafa', 137 | springgreen: '#00ff7f', 138 | steelblue: '#4682b4', 139 | tan: '#d2b48c', 140 | teal: '#008080', 141 | thistle: '#d8bfd8', 142 | tomato: '#ff6347', 143 | turquoise: '#40e0d0', 144 | violet: '#ee82ee', 145 | wheat: '#f5deb3', 146 | white: '#fff', 147 | whitesmoke: '#f5f5f5', 148 | yellow: '#ff0', 149 | yellowgreen: '#9acd32' 150 | }; 151 | 152 | var toHex = {}; 153 | var toName = {}; 154 | 155 | for (var name in COLORS) { 156 | var hex = COLORS[name]; 157 | 158 | if (name.length < hex.length) { 159 | toName[hex] = name; 160 | } else { 161 | toHex[name] = hex; 162 | } 163 | } 164 | 165 | var toHexPattern = new RegExp('(^| |,|\\))(' + Object.keys(toHex).join('|') + ')( |,|\\)|$)', 'ig'); 166 | var toNamePattern = new RegExp('(' + Object.keys(toName).join('|') + ')([^a-f0-9]|$)', 'ig'); 167 | 168 | function hexConverter(match, prefix, colorValue, suffix) { 169 | return prefix + toHex[colorValue.toLowerCase()] + suffix; 170 | } 171 | 172 | function nameConverter(match, colorValue, suffix) { 173 | return toName[colorValue.toLowerCase()] + suffix; 174 | } 175 | 176 | function shortenHex(value) { 177 | var hasHex = value.indexOf('#') > -1; 178 | var shortened = value.replace(toHexPattern, hexConverter); 179 | 180 | if (shortened != value) { 181 | shortened = shortened.replace(toHexPattern, hexConverter); 182 | } 183 | 184 | return hasHex ? 185 | shortened.replace(toNamePattern, nameConverter) : 186 | shortened; 187 | } 188 | 189 | module.exports = shortenHex; 190 | -------------------------------------------------------------------------------- /test-ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 5 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 6 | // "lib": [], /* Specify library files to be included in the compilation. */ 7 | // "allowJs": true, /* Allow javascript files to be compiled. */ 8 | // "checkJs": true, /* Report errors in .js files. */ 9 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 10 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 11 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 12 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 13 | // "outFile": "./", /* Concatenate and emit output to single file. */ 14 | // "outDir": "./", /* Redirect output structure to the directory. */ 15 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 16 | // "composite": true, /* Enable project compilation */ 17 | // "incremental": true, /* Enable incremental compilation */ 18 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 19 | // "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | "strict": true, /* Enable all strict type-checking options. */ 27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 31 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 32 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 33 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 34 | 35 | /* Additional Checks */ 36 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 37 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 38 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 39 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 40 | 41 | /* Module Resolution Options */ 42 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 43 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 44 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 45 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 46 | // "typeRoots": [], /* List of folders to include type definitions from. */ 47 | // "types": [], /* Type declaration files to be included in compilation. */ 48 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 49 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 50 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 51 | 52 | /* Source Map Options */ 53 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 54 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 55 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 56 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 57 | 58 | /* Experimental Options */ 59 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 60 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 61 | } 62 | } 63 | --------------------------------------------------------------------------------