init commit
This commit is contained in:
11
.babelrc
Normal file
11
.babelrc
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
["module-resolver", {
|
||||||
|
"root": ["./src"],
|
||||||
|
"alias": {}
|
||||||
|
}]
|
||||||
|
],
|
||||||
|
"presets": [
|
||||||
|
["env", {"loose": true, "modules": "commonjs"}]
|
||||||
|
]
|
||||||
|
}
|
||||||
96
.eslintrc.js
Normal file
96
.eslintrc.js
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
module.exports = {
|
||||||
|
'extends': [
|
||||||
|
'airbnb-base',
|
||||||
|
'plugin:promise/recommended'
|
||||||
|
],
|
||||||
|
'parserOptions': {
|
||||||
|
'ecmaVersion': 9,
|
||||||
|
'ecmaFeatures': {
|
||||||
|
'jsx': false
|
||||||
|
},
|
||||||
|
'sourceType': 'module'
|
||||||
|
},
|
||||||
|
'env': {
|
||||||
|
'es6': true,
|
||||||
|
'node': true,
|
||||||
|
'jest': true
|
||||||
|
},
|
||||||
|
'plugins': [
|
||||||
|
'import',
|
||||||
|
'node',
|
||||||
|
'promise'
|
||||||
|
],
|
||||||
|
'rules': {
|
||||||
|
'arrow-parens': 'off',
|
||||||
|
'comma-dangle': [
|
||||||
|
'error',
|
||||||
|
'only-multiline'
|
||||||
|
],
|
||||||
|
'complexity': ['error', 10],
|
||||||
|
'func-names': 'off',
|
||||||
|
'global-require': 'off',
|
||||||
|
'handle-callback-err': [
|
||||||
|
'error',
|
||||||
|
'^(err|error)$'
|
||||||
|
],
|
||||||
|
'import/no-unresolved': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
'caseSensitive': true,
|
||||||
|
'commonjs': true,
|
||||||
|
'ignore': ['^[^.]']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'import/prefer-default-export': 'off',
|
||||||
|
'linebreak-style': 'off',
|
||||||
|
'no-catch-shadow': 'error',
|
||||||
|
'no-continue': 'off',
|
||||||
|
'no-div-regex': 'warn',
|
||||||
|
'no-else-return': 'off',
|
||||||
|
'no-param-reassign': 'off',
|
||||||
|
'no-plusplus': 'off',
|
||||||
|
'no-shadow': 'off',
|
||||||
|
'no-multi-assign': 'off',
|
||||||
|
'no-underscore-dangle': 'off',
|
||||||
|
'node/no-deprecated-api': 'error',
|
||||||
|
'node/process-exit-as-throw': 'error',
|
||||||
|
'object-curly-spacing': [
|
||||||
|
'error',
|
||||||
|
'never'
|
||||||
|
],
|
||||||
|
'operator-linebreak': [
|
||||||
|
'error',
|
||||||
|
'after',
|
||||||
|
{
|
||||||
|
'overrides': {
|
||||||
|
':': 'before',
|
||||||
|
'?': 'before'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'prefer-arrow-callback': 'off',
|
||||||
|
'prefer-destructuring': 'off',
|
||||||
|
'prefer-template': 'off',
|
||||||
|
'quote-props': [
|
||||||
|
1,
|
||||||
|
'as-needed',
|
||||||
|
{
|
||||||
|
'unnecessary': true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'semi': [
|
||||||
|
'error',
|
||||||
|
'never'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'globals': {
|
||||||
|
'window': true,
|
||||||
|
'document': true,
|
||||||
|
'App': true,
|
||||||
|
'Page': true,
|
||||||
|
'Component': true,
|
||||||
|
'Behavior': true,
|
||||||
|
'wx': true,
|
||||||
|
'getCurrentPages': true,
|
||||||
|
}
|
||||||
|
}
|
||||||
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
miniprogram_dist
|
||||||
|
miniprogram_dev
|
||||||
|
node_modules
|
||||||
|
coverage
|
||||||
16
.npmignore
Normal file
16
.npmignore
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
test
|
||||||
|
tools
|
||||||
|
docs
|
||||||
|
miniprogram_dev
|
||||||
|
node_modules
|
||||||
|
coverage
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 wechat-miniprogram
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
26
gulpfile.js
Normal file
26
gulpfile.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
const gulp = require('gulp')
|
||||||
|
const clean = require('gulp-clean')
|
||||||
|
|
||||||
|
const config = require('./tools/config')
|
||||||
|
const BuildTask = require('./tools/build')
|
||||||
|
const id = require('./package.json').name || 'miniprogram-custom-component'
|
||||||
|
|
||||||
|
// build task instance
|
||||||
|
// eslint-disable-next-line no-new
|
||||||
|
new BuildTask(id, config.entry)
|
||||||
|
|
||||||
|
// clean the generated folders and files
|
||||||
|
gulp.task('clean', gulp.series(() => gulp.src(config.distPath, {read: false, allowEmpty: true}).pipe(clean()), done => {
|
||||||
|
if (config.isDev) {
|
||||||
|
return gulp.src(config.demoDist, {read: false, allowEmpty: true})
|
||||||
|
.pipe(clean())
|
||||||
|
}
|
||||||
|
|
||||||
|
return done()
|
||||||
|
}))
|
||||||
|
// watch files and build
|
||||||
|
gulp.task('watch', gulp.series(`${id}-watch`))
|
||||||
|
// build for develop
|
||||||
|
gulp.task('dev', gulp.series(`${id}-dev`))
|
||||||
|
// build for publish
|
||||||
|
gulp.task('default', gulp.series(`${id}-default`))
|
||||||
62
package.json
Normal file
62
package.json
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"name": "miniprogram-picker",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "miniprogram_dist/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "gulp dev --develop",
|
||||||
|
"watch": "gulp watch --develop --watch",
|
||||||
|
"build": "gulp",
|
||||||
|
"dist": "npm run build",
|
||||||
|
"clean-dev": "gulp clean --develop",
|
||||||
|
"clean": "gulp clean",
|
||||||
|
"test": "jest ./test/* --silent --bail",
|
||||||
|
"coverage": "jest ./test/* --coverage --bail",
|
||||||
|
"lint": "eslint \"src/**/*.js\"",
|
||||||
|
"lint-tools": "eslint \"tools/**/*.js\" --rule \"import/no-extraneous-dependencies: false\""
|
||||||
|
},
|
||||||
|
"miniprogram": "miniprogram_dist",
|
||||||
|
"jest": {
|
||||||
|
"testEnvironment": "jsdom",
|
||||||
|
"testURL": "https://jest.test",
|
||||||
|
"collectCoverageFrom": [
|
||||||
|
"src/**/*.js"
|
||||||
|
],
|
||||||
|
"moduleDirectories": [
|
||||||
|
"node_modules",
|
||||||
|
"src"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/IceApriler/miniprogram-picker.git"
|
||||||
|
},
|
||||||
|
"author": "wechat-miniprogram",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.26.3",
|
||||||
|
"babel-loader": "^7.1.5",
|
||||||
|
"babel-plugin-module-resolver": "^3.1.1",
|
||||||
|
"babel-preset-env": "^1.7.0",
|
||||||
|
"colors": "^1.3.1",
|
||||||
|
"eslint": "^5.3.0",
|
||||||
|
"eslint-config-airbnb-base": "13.1.0",
|
||||||
|
"eslint-loader": "^2.1.0",
|
||||||
|
"eslint-plugin-import": "^2.14.0",
|
||||||
|
"eslint-plugin-node": "^7.0.1",
|
||||||
|
"eslint-plugin-promise": "^3.8.0",
|
||||||
|
"gulp": "^4.0.0",
|
||||||
|
"gulp-clean": "^0.4.0",
|
||||||
|
"gulp-if": "^2.0.2",
|
||||||
|
"gulp-install": "^1.1.0",
|
||||||
|
"gulp-less": "^3.5.0",
|
||||||
|
"gulp-rename": "^1.4.0",
|
||||||
|
"gulp-sourcemaps": "^2.6.4",
|
||||||
|
"jest": "^23.5.0",
|
||||||
|
"miniprogram-simulate": "^0.1.3",
|
||||||
|
"through2": "^2.0.3",
|
||||||
|
"webpack": "^4.16.5",
|
||||||
|
"webpack-node-externals": "^1.7.2"
|
||||||
|
},
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
||||||
22
src/index.js
Normal file
22
src/index.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
Component({
|
||||||
|
properties: {
|
||||||
|
prop: {
|
||||||
|
type: String,
|
||||||
|
value: 'index.properties'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
flag: false,
|
||||||
|
},
|
||||||
|
lifetimes: {
|
||||||
|
attached() {
|
||||||
|
wx.getSystemInfo({
|
||||||
|
success: res => {
|
||||||
|
this.setData({
|
||||||
|
flag: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
4
src/index.json
Normal file
4
src/index.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
||||||
1
src/index.wxml
Normal file
1
src/index.wxml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<view class="index">{{prop}}-{{flag}}</view>
|
||||||
3
src/index.wxss
Normal file
3
src/index.wxss
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.index {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
15
test/index.test.js
Normal file
15
test/index.test.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
const _ = require('./utils')
|
||||||
|
|
||||||
|
test('render', async () => {
|
||||||
|
const componentId = _.load('index', 'comp')
|
||||||
|
const component = _.render(componentId, {prop: 'index.test.properties'})
|
||||||
|
|
||||||
|
const parent = document.createElement('parent-wrapper')
|
||||||
|
component.attach(parent)
|
||||||
|
|
||||||
|
expect(_.match(component.dom, '<wx-view class="comp--index">index.test.properties-false</wx-view>')).toBe(true)
|
||||||
|
|
||||||
|
await _.sleep(10)
|
||||||
|
|
||||||
|
expect(_.match(component.dom, '<wx-view class="comp--index">index.test.properties-true</wx-view>')).toBe(true)
|
||||||
|
})
|
||||||
22
test/utils.js
Normal file
22
test/utils.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
const path = require('path')
|
||||||
|
const simulate = require('miniprogram-simulate')
|
||||||
|
|
||||||
|
const config = require('../tools/config')
|
||||||
|
|
||||||
|
const srcPath = config.srcPath
|
||||||
|
const oldLoad = simulate.load
|
||||||
|
simulate.load = function (componentPath, ...args) {
|
||||||
|
componentPath = path.join(srcPath, componentPath)
|
||||||
|
return oldLoad(componentPath, ...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = simulate
|
||||||
|
|
||||||
|
// adjust the simulated wx api
|
||||||
|
const oldGetSystemInfoSync = global.wx.getSystemInfoSync
|
||||||
|
global.wx.getSystemInfoSync = function() {
|
||||||
|
const res = oldGetSystemInfoSync()
|
||||||
|
res.SDKVersion = '2.4.1'
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
18
test/wx.test.js
Normal file
18
test/wx.test.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
const _ = require('./utils')
|
||||||
|
|
||||||
|
test('wx.getSystemInfo', async () => {
|
||||||
|
wx.getSystemInfo({
|
||||||
|
success(res) {
|
||||||
|
expect(res.errMsg).toBe('getSystemInfo:ok')
|
||||||
|
},
|
||||||
|
complete(res) {
|
||||||
|
expect(res.errMsg).toBe('getSystemInfo:ok')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('wx.getSystemInfoSync', async () => {
|
||||||
|
const info = wx.getSystemInfoSync()
|
||||||
|
expect(info.SDKVersion).toBe('2.4.1')
|
||||||
|
expect(info.version).toBe('6.6.3')
|
||||||
|
})
|
||||||
318
tools/build.js
Normal file
318
tools/build.js
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const gulp = require('gulp')
|
||||||
|
const clean = require('gulp-clean')
|
||||||
|
const less = require('gulp-less')
|
||||||
|
const rename = require('gulp-rename')
|
||||||
|
const gulpif = require('gulp-if')
|
||||||
|
const sourcemaps = require('gulp-sourcemaps')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
const gulpInstall = require('gulp-install')
|
||||||
|
|
||||||
|
const config = require('./config')
|
||||||
|
const checkComponents = require('./checkcomponents')
|
||||||
|
const _ = require('./utils')
|
||||||
|
|
||||||
|
const wxssConfig = config.wxss || {}
|
||||||
|
const srcPath = config.srcPath
|
||||||
|
const distPath = config.distPath
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get wxss stream
|
||||||
|
*/
|
||||||
|
function wxss(wxssFileList) {
|
||||||
|
if (!wxssFileList.length) return false
|
||||||
|
|
||||||
|
return gulp.src(wxssFileList, {cwd: srcPath, base: srcPath})
|
||||||
|
.pipe(gulpif(wxssConfig.less && wxssConfig.sourcemap, sourcemaps.init()))
|
||||||
|
.pipe(gulpif(wxssConfig.less, less({paths: [srcPath]})))
|
||||||
|
.pipe(rename({extname: '.wxss'}))
|
||||||
|
.pipe(gulpif(wxssConfig.less && wxssConfig.sourcemap, sourcemaps.write('./')))
|
||||||
|
.pipe(_.logger(wxssConfig.less ? 'generate' : undefined))
|
||||||
|
.pipe(gulp.dest(distPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get js stream
|
||||||
|
*/
|
||||||
|
function js(jsFileMap, scope) {
|
||||||
|
const webpackConfig = config.webpack
|
||||||
|
const webpackCallback = (err, stats) => {
|
||||||
|
if (!err) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(stats.toString({
|
||||||
|
assets: true,
|
||||||
|
cached: false,
|
||||||
|
colors: true,
|
||||||
|
children: false,
|
||||||
|
errors: true,
|
||||||
|
warnings: true,
|
||||||
|
version: true,
|
||||||
|
modules: false,
|
||||||
|
publicPath: true,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
webpackConfig.entry = jsFileMap
|
||||||
|
webpackConfig.output.path = distPath
|
||||||
|
|
||||||
|
if (scope.webpackWatcher) {
|
||||||
|
scope.webpackWatcher.close()
|
||||||
|
scope.webpackWatcher = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.isWatch) {
|
||||||
|
scope.webpackWatcher = webpack(webpackConfig).watch({
|
||||||
|
ignored: /node_modules/,
|
||||||
|
}, webpackCallback)
|
||||||
|
} else {
|
||||||
|
webpack(webpackConfig).run(webpackCallback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy file
|
||||||
|
*/
|
||||||
|
function copy(copyFileList) {
|
||||||
|
if (!copyFileList.length) return false
|
||||||
|
|
||||||
|
return gulp.src(copyFileList, {cwd: srcPath, base: srcPath})
|
||||||
|
.pipe(_.logger())
|
||||||
|
.pipe(gulp.dest(distPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* install packages
|
||||||
|
*/
|
||||||
|
function install() {
|
||||||
|
return gulp.series(async () => {
|
||||||
|
const demoDist = config.demoDist
|
||||||
|
const demoPackageJsonPath = path.join(demoDist, 'package.json')
|
||||||
|
const packageJson = _.readJson(path.resolve(__dirname, '../package.json'))
|
||||||
|
const dependencies = packageJson.dependencies || {}
|
||||||
|
|
||||||
|
await _.writeFile(demoPackageJsonPath, JSON.stringify({dependencies}, null, '\t')) // write dev demo's package.json
|
||||||
|
}, () => {
|
||||||
|
const demoDist = config.demoDist
|
||||||
|
const demoPackageJsonPath = path.join(demoDist, 'package.json')
|
||||||
|
|
||||||
|
return gulp.src(demoPackageJsonPath)
|
||||||
|
.pipe(gulpInstall({production: true}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
class BuildTask {
|
||||||
|
constructor(id, entry) {
|
||||||
|
if (!entry) return
|
||||||
|
|
||||||
|
this.id = id
|
||||||
|
this.entries = Array.isArray(config.entry) ? config.entry : [config.entry]
|
||||||
|
this.copyList = Array.isArray(config.copy) ? config.copy : []
|
||||||
|
this.componentListMap = {}
|
||||||
|
this.cachedComponentListMap = {}
|
||||||
|
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
const id = this.id
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clean the dist folder
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-clean-dist`, () => gulp.src(distPath, {read: false, allowEmpty: true}).pipe(clean()))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy demo to the dev folder
|
||||||
|
*/
|
||||||
|
let isDemoExists = false
|
||||||
|
gulp.task(`${id}-demo`, gulp.series(async () => {
|
||||||
|
const demoDist = config.demoDist
|
||||||
|
|
||||||
|
isDemoExists = await _.checkFileExists(path.join(demoDist, 'project.config.json'))
|
||||||
|
}, done => {
|
||||||
|
if (!isDemoExists) {
|
||||||
|
const demoSrc = config.demoSrc
|
||||||
|
const demoDist = config.demoDist
|
||||||
|
|
||||||
|
return gulp.src('**/*', {cwd: demoSrc, base: demoSrc})
|
||||||
|
.pipe(gulp.dest(demoDist))
|
||||||
|
}
|
||||||
|
|
||||||
|
return done()
|
||||||
|
}))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* install packages for dev
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-install`, install())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check custom components
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-component-check`, async () => {
|
||||||
|
const entries = this.entries
|
||||||
|
const mergeComponentListMap = {}
|
||||||
|
for (let i = 0, len = entries.length; i < len; i++) {
|
||||||
|
let entry = entries[i]
|
||||||
|
entry = path.join(srcPath, `${entry}.json`)
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const newComponentListMap = await checkComponents(entry)
|
||||||
|
|
||||||
|
_.merge(mergeComponentListMap, newComponentListMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cachedComponentListMap = this.componentListMap
|
||||||
|
this.componentListMap = mergeComponentListMap
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write json to the dist folder
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-component-json`, done => {
|
||||||
|
const jsonFileList = this.componentListMap.jsonFileList
|
||||||
|
|
||||||
|
if (jsonFileList && jsonFileList.length) {
|
||||||
|
return copy(this.componentListMap.jsonFileList)
|
||||||
|
}
|
||||||
|
|
||||||
|
return done()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy wxml to the dist folder
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-component-wxml`, done => {
|
||||||
|
const wxmlFileList = this.componentListMap.wxmlFileList
|
||||||
|
|
||||||
|
if (wxmlFileList &&
|
||||||
|
wxmlFileList.length &&
|
||||||
|
!_.compareArray(this.cachedComponentListMap.wxmlFileList, wxmlFileList)) {
|
||||||
|
return copy(wxmlFileList)
|
||||||
|
}
|
||||||
|
|
||||||
|
return done()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate wxss to the dist folder
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-component-wxss`, done => {
|
||||||
|
const wxssFileList = this.componentListMap.wxssFileList
|
||||||
|
|
||||||
|
if (wxssFileList &&
|
||||||
|
wxssFileList.length &&
|
||||||
|
!_.compareArray(this.cachedComponentListMap.wxssFileList, wxssFileList)) {
|
||||||
|
return wxss(wxssFileList, srcPath, distPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return done()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate js to the dist folder
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-component-js`, done => {
|
||||||
|
const jsFileList = this.componentListMap.jsFileList
|
||||||
|
|
||||||
|
if (jsFileList &&
|
||||||
|
jsFileList.length &&
|
||||||
|
!_.compareArray(this.cachedComponentListMap.jsFileList, jsFileList)) {
|
||||||
|
js(this.componentListMap.jsFileMap, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
return done()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy resources to dist folder
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-copy`, gulp.parallel(done => {
|
||||||
|
const copyList = this.copyList
|
||||||
|
const copyFileList = copyList.map(dir => path.join(dir, '**/*.!(wxss)'))
|
||||||
|
|
||||||
|
if (copyFileList.length) return copy(copyFileList)
|
||||||
|
|
||||||
|
return done()
|
||||||
|
}, done => {
|
||||||
|
const copyList = this.copyList
|
||||||
|
const copyFileList = copyList.map(dir => path.join(dir, '**/*.wxss'))
|
||||||
|
|
||||||
|
if (copyFileList.length) return wxss(copyFileList, srcPath, distPath)
|
||||||
|
|
||||||
|
return done()
|
||||||
|
}))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watch json
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-watch-json`, () => gulp.watch(this.componentListMap.jsonFileList, {cwd: srcPath, base: srcPath}, gulp.series(`${id}-component-check`, gulp.parallel(`${id}-component-wxml`, `${id}-component-wxss`, `${id}-component-js`, `${id}-component-json`))))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watch wxml
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-watch-wxml`, () => {
|
||||||
|
this.cachedComponentListMap.wxmlFileList = null
|
||||||
|
return gulp.watch(this.componentListMap.wxmlFileList, {cwd: srcPath, base: srcPath}, gulp.series(`${id}-component-wxml`))
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watch wxss
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-watch-wxss`, () => {
|
||||||
|
this.cachedComponentListMap.wxssFileList = null
|
||||||
|
return gulp.watch('**/*.wxss', {cwd: srcPath, base: srcPath}, gulp.series(`${id}-component-wxss`))
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watch resources
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-watch-copy`, () => {
|
||||||
|
const copyList = this.copyList
|
||||||
|
const copyFileList = copyList.map(dir => path.join(dir, '**/*'))
|
||||||
|
const watchCallback = filePath => copy([filePath])
|
||||||
|
|
||||||
|
return gulp.watch(copyFileList, {cwd: srcPath, base: srcPath})
|
||||||
|
.on('change', watchCallback)
|
||||||
|
.on('add', watchCallback)
|
||||||
|
.on('unlink', watchCallback)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watch demo
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-watch-demo`, () => {
|
||||||
|
const demoSrc = config.demoSrc
|
||||||
|
const demoDist = config.demoDist
|
||||||
|
const watchCallback = filePath => gulp.src(filePath, {cwd: demoSrc, base: demoSrc})
|
||||||
|
.pipe(gulp.dest(demoDist))
|
||||||
|
|
||||||
|
return gulp.watch('**/*', {cwd: demoSrc, base: demoSrc})
|
||||||
|
.on('change', watchCallback)
|
||||||
|
.on('add', watchCallback)
|
||||||
|
.on('unlink', watchCallback)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watch installed packages
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-watch-install`, () => gulp.watch(path.resolve(__dirname, '../package.json'), install()))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build custom component
|
||||||
|
*/
|
||||||
|
gulp.task(`${id}-build`, gulp.series(`${id}-clean-dist`, `${id}-component-check`, gulp.parallel(`${id}-component-wxml`, `${id}-component-wxss`, `${id}-component-js`, `${id}-component-json`, `${id}-copy`)))
|
||||||
|
|
||||||
|
gulp.task(`${id}-watch`, gulp.series(`${id}-build`, `${id}-demo`, `${id}-install`, gulp.parallel(`${id}-watch-wxml`, `${id}-watch-wxss`, `${id}-watch-json`, `${id}-watch-copy`, `${id}-watch-install`, `${id}-watch-demo`)))
|
||||||
|
|
||||||
|
gulp.task(`${id}-dev`, gulp.series(`${id}-build`, `${id}-demo`, `${id}-install`))
|
||||||
|
|
||||||
|
gulp.task(`${id}-default`, gulp.series(`${id}-build`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BuildTask
|
||||||
87
tools/checkcomponents.js
Normal file
87
tools/checkcomponents.js
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const _ = require('./utils')
|
||||||
|
const config = require('./config')
|
||||||
|
|
||||||
|
const srcPath = config.srcPath
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get json path's info
|
||||||
|
*/
|
||||||
|
function getJsonPathInfo(jsonPath) {
|
||||||
|
const dirPath = path.dirname(jsonPath)
|
||||||
|
const fileName = path.basename(jsonPath, '.json')
|
||||||
|
const relative = path.relative(srcPath, dirPath)
|
||||||
|
const fileBase = path.join(relative, fileName)
|
||||||
|
|
||||||
|
return {
|
||||||
|
dirPath, fileName, relative, fileBase
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check included components
|
||||||
|
*/
|
||||||
|
const checkProps = ['usingComponents', 'componentGenerics']
|
||||||
|
async function checkIncludedComponents(jsonPath, componentListMap) {
|
||||||
|
const json = _.readJson(jsonPath)
|
||||||
|
if (!json) throw new Error(`json is not valid: "${jsonPath}"`)
|
||||||
|
|
||||||
|
const {dirPath, fileName, fileBase} = getJsonPathInfo(jsonPath)
|
||||||
|
|
||||||
|
for (let i = 0, len = checkProps.length; i < len; i++) {
|
||||||
|
const checkProp = checkProps[i]
|
||||||
|
const checkPropValue = json[checkProp] || {}
|
||||||
|
const keys = Object.keys(checkPropValue)
|
||||||
|
|
||||||
|
for (let j = 0, jlen = keys.length; j < jlen; j++) {
|
||||||
|
const key = keys[j]
|
||||||
|
let value = typeof checkPropValue[key] === 'object' ? checkPropValue[key].default : checkPropValue[key]
|
||||||
|
if (!value) continue
|
||||||
|
|
||||||
|
value = _.transformPath(value, path.sep)
|
||||||
|
|
||||||
|
// check relative path
|
||||||
|
const componentPath = `${path.join(dirPath, value)}.json`
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const isExists = await _.checkFileExists(componentPath)
|
||||||
|
if (isExists) {
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
await checkIncludedComponents(componentPath, componentListMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// checked
|
||||||
|
componentListMap.wxmlFileList.push(`${fileBase}.wxml`)
|
||||||
|
componentListMap.wxssFileList.push(`${fileBase}.wxss`)
|
||||||
|
componentListMap.jsonFileList.push(`${fileBase}.json`)
|
||||||
|
componentListMap.jsFileList.push(`${fileBase}.js`)
|
||||||
|
|
||||||
|
componentListMap.jsFileMap[fileBase] = `${path.join(dirPath, fileName)}.js`
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = async function (entry) {
|
||||||
|
const componentListMap = {
|
||||||
|
wxmlFileList: [],
|
||||||
|
wxssFileList: [],
|
||||||
|
jsonFileList: [],
|
||||||
|
jsFileList: [],
|
||||||
|
|
||||||
|
jsFileMap: {}, // for webpack entry
|
||||||
|
}
|
||||||
|
|
||||||
|
const isExists = await _.checkFileExists(entry)
|
||||||
|
if (!isExists) {
|
||||||
|
const {dirPath, fileName, fileBase} = getJsonPathInfo(entry)
|
||||||
|
|
||||||
|
componentListMap.jsFileList.push(`${fileBase}.js`)
|
||||||
|
componentListMap.jsFileMap[fileBase] = `${path.join(dirPath, fileName)}.js`
|
||||||
|
|
||||||
|
return componentListMap
|
||||||
|
}
|
||||||
|
|
||||||
|
await checkIncludedComponents(entry, componentListMap)
|
||||||
|
|
||||||
|
return componentListMap
|
||||||
|
}
|
||||||
67
tools/config.js
Normal file
67
tools/config.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const webpack = require('webpack')
|
||||||
|
const nodeExternals = require('webpack-node-externals')
|
||||||
|
|
||||||
|
const isDev = process.argv.indexOf('--develop') >= 0
|
||||||
|
const isWatch = process.argv.indexOf('--watch') >= 0
|
||||||
|
const demoSrc = path.resolve(__dirname, './demo')
|
||||||
|
const demoDist = path.resolve(__dirname, '../miniprogram_dev')
|
||||||
|
const src = path.resolve(__dirname, '../src')
|
||||||
|
const dev = path.join(demoDist, 'components')
|
||||||
|
const dist = path.resolve(__dirname, '../miniprogram_dist')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: ['index'],
|
||||||
|
|
||||||
|
isDev,
|
||||||
|
isWatch,
|
||||||
|
srcPath: src,
|
||||||
|
distPath: isDev ? dev : dist,
|
||||||
|
|
||||||
|
demoSrc,
|
||||||
|
demoDist,
|
||||||
|
|
||||||
|
wxss: {
|
||||||
|
less: false, // compile wxss with less
|
||||||
|
sourcemap: false, // source map for less
|
||||||
|
},
|
||||||
|
|
||||||
|
webpack: {
|
||||||
|
mode: 'production',
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
libraryTarget: 'commonjs2',
|
||||||
|
},
|
||||||
|
target: 'node',
|
||||||
|
externals: [nodeExternals()], // ignore node_modules
|
||||||
|
module: {
|
||||||
|
rules: [{
|
||||||
|
test: /\.js$/i,
|
||||||
|
use: [
|
||||||
|
'babel-loader',
|
||||||
|
'eslint-loader'
|
||||||
|
],
|
||||||
|
exclude: /node_modules/
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
modules: [src, 'node_modules'],
|
||||||
|
extensions: ['.js', '.json'],
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.DefinePlugin({}),
|
||||||
|
new webpack.optimize.LimitChunkCountPlugin({maxChunks: 1}),
|
||||||
|
],
|
||||||
|
optimization: {
|
||||||
|
minimize: false,
|
||||||
|
},
|
||||||
|
// devtool: 'nosources-source-map', // source map for js
|
||||||
|
performance: {
|
||||||
|
hints: 'warning',
|
||||||
|
assetFilter: assetFilename => assetFilename.endsWith('.js')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
copy: ['./wxml', './wxss', './wxs', './images'], // will copy to dist
|
||||||
|
}
|
||||||
1
tools/demo/app.js
Normal file
1
tools/demo/app.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
App({})
|
||||||
11
tools/demo/app.json
Normal file
11
tools/demo/app.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"pages":[
|
||||||
|
"pages/index/index"
|
||||||
|
],
|
||||||
|
"window":{
|
||||||
|
"backgroundTextStyle":"light",
|
||||||
|
"navigationBarBackgroundColor": "#fff",
|
||||||
|
"navigationBarTitleText": "WeChat",
|
||||||
|
"navigationBarTextStyle":"black"
|
||||||
|
}
|
||||||
|
}
|
||||||
0
tools/demo/app.wxss
Normal file
0
tools/demo/app.wxss
Normal file
1
tools/demo/package.json
Normal file
1
tools/demo/package.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
tools/demo/pages/index/index.js
Normal file
1
tools/demo/pages/index/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Page({})
|
||||||
5
tools/demo/pages/index/index.json
Normal file
5
tools/demo/pages/index/index.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {
|
||||||
|
"comp": "../../components/index"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
tools/demo/pages/index/index.wxml
Normal file
1
tools/demo/pages/index/index.wxml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<comp></comp>
|
||||||
0
tools/demo/pages/index/index.wxss
Normal file
0
tools/demo/pages/index/index.wxss
Normal file
37
tools/demo/project.config.json
Normal file
37
tools/demo/project.config.json
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"description": "项目配置文件。",
|
||||||
|
"packOptions": {
|
||||||
|
"ignore": []
|
||||||
|
},
|
||||||
|
"setting": {
|
||||||
|
"urlCheck": true,
|
||||||
|
"es6": true,
|
||||||
|
"postcss": true,
|
||||||
|
"minified": true,
|
||||||
|
"newFeature": true,
|
||||||
|
"nodeModules": true
|
||||||
|
},
|
||||||
|
"compileType": "miniprogram",
|
||||||
|
"libVersion": "2.2.3",
|
||||||
|
"appid": "",
|
||||||
|
"projectname": "miniprogram-demo",
|
||||||
|
"isGameTourist": false,
|
||||||
|
"condition": {
|
||||||
|
"search": {
|
||||||
|
"current": -1,
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"conversation": {
|
||||||
|
"current": -1,
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"game": {
|
||||||
|
"currentL": -1,
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"miniprogram": {
|
||||||
|
"current": -1,
|
||||||
|
"list": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
213
tools/utils.js
Normal file
213
tools/utils.js
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
const colors = require('colors')
|
||||||
|
const through = require('through2')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* async function wrapper
|
||||||
|
*/
|
||||||
|
function wrap(func, scope) {
|
||||||
|
return function (...args) {
|
||||||
|
if (args.length) {
|
||||||
|
const temp = args.pop()
|
||||||
|
if (typeof temp !== 'function') {
|
||||||
|
args.push(temp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
args.push(function (err, data) {
|
||||||
|
if (err) reject(err)
|
||||||
|
else resolve(data)
|
||||||
|
})
|
||||||
|
|
||||||
|
func.apply((scope || null), args)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const accessSync = wrap(fs.access)
|
||||||
|
const statSync = wrap(fs.stat)
|
||||||
|
const renameSync = wrap(fs.rename)
|
||||||
|
const mkdirSync = wrap(fs.mkdir)
|
||||||
|
const readFileSync = wrap(fs.readFile)
|
||||||
|
const writeFileSync = wrap(fs.writeFile)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* transform path segment separator
|
||||||
|
*/
|
||||||
|
function transformPath(filePath, sep = '/') {
|
||||||
|
return filePath.replace(/[\\/]/g, sep)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check file exists
|
||||||
|
*/
|
||||||
|
async function checkFileExists(filePath) {
|
||||||
|
try {
|
||||||
|
await accessSync(filePath)
|
||||||
|
return true
|
||||||
|
} catch (err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create folder
|
||||||
|
*/
|
||||||
|
async function recursiveMkdir(dirPath) {
|
||||||
|
const prevDirPath = path.dirname(dirPath)
|
||||||
|
try {
|
||||||
|
await accessSync(prevDirPath)
|
||||||
|
} catch (err) {
|
||||||
|
// prevDirPath is not exist
|
||||||
|
await recursiveMkdir(prevDirPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await accessSync(dirPath)
|
||||||
|
|
||||||
|
const stat = await statSync(dirPath)
|
||||||
|
if (stat && !stat.isDirectory()) {
|
||||||
|
// dirPath already exists but is not a directory
|
||||||
|
await renameSync(dirPath, `${dirPath}.bak`) // rename to a file with the suffix ending in '.bak'
|
||||||
|
await mkdirSync(dirPath)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// dirPath is not exist
|
||||||
|
await mkdirSync(dirPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read json
|
||||||
|
*/
|
||||||
|
function readJson(filePath) {
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line import/no-dynamic-require
|
||||||
|
const content = require(filePath)
|
||||||
|
delete require.cache[require.resolve(filePath)]
|
||||||
|
return content
|
||||||
|
} catch (err) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read file
|
||||||
|
*/
|
||||||
|
async function readFile(filePath) {
|
||||||
|
try {
|
||||||
|
return await readFileSync(filePath, 'utf8')
|
||||||
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
return console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write file
|
||||||
|
*/
|
||||||
|
async function writeFile(filePath, data) {
|
||||||
|
try {
|
||||||
|
await recursiveMkdir(path.dirname(filePath))
|
||||||
|
return await writeFileSync(filePath, data, 'utf8')
|
||||||
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
return console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* time format
|
||||||
|
*/
|
||||||
|
function format(time, reg) {
|
||||||
|
const date = typeof time === 'string' ? new Date(time) : time
|
||||||
|
const map = {}
|
||||||
|
map.yyyy = date.getFullYear()
|
||||||
|
map.yy = ('' + map.yyyy).substr(2)
|
||||||
|
map.M = date.getMonth() + 1
|
||||||
|
map.MM = (map.M < 10 ? '0' : '') + map.M
|
||||||
|
map.d = date.getDate()
|
||||||
|
map.dd = (map.d < 10 ? '0' : '') + map.d
|
||||||
|
map.H = date.getHours()
|
||||||
|
map.HH = (map.H < 10 ? '0' : '') + map.H
|
||||||
|
map.m = date.getMinutes()
|
||||||
|
map.mm = (map.m < 10 ? '0' : '') + map.m
|
||||||
|
map.s = date.getSeconds()
|
||||||
|
map.ss = (map.s < 10 ? '0' : '') + map.s
|
||||||
|
|
||||||
|
return reg.replace(/\byyyy|yy|MM|M|dd|d|HH|H|mm|m|ss|s\b/g, $1 => map[$1])
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logger plugin
|
||||||
|
*/
|
||||||
|
function logger(action = 'copy') {
|
||||||
|
return through.obj(function (file, enc, cb) {
|
||||||
|
const type = path.extname(file.path).slice(1).toLowerCase()
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(`[${format(new Date(), 'yyyy-MM-dd HH:mm:ss').grey}] [${action.green} ${type.green}] ${'=>'.cyan} ${file.path}`)
|
||||||
|
|
||||||
|
this.push(file)
|
||||||
|
cb()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* compare arrays
|
||||||
|
*/
|
||||||
|
function compareArray(arr1, arr2) {
|
||||||
|
if (!Array.isArray(arr1) || !Array.isArray(arr2)) return false
|
||||||
|
if (arr1.length !== arr2.length) return false
|
||||||
|
|
||||||
|
for (let i = 0, len = arr1.length; i < len; i++) {
|
||||||
|
if (arr1[i] !== arr2[i]) return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* merge two object
|
||||||
|
*/
|
||||||
|
function merge(obj1, obj2) {
|
||||||
|
Object.keys(obj2).forEach(key => {
|
||||||
|
if (Array.isArray(obj1[key]) && Array.isArray(obj2[key])) {
|
||||||
|
obj1[key] = obj1[key].concat(obj2[key])
|
||||||
|
} else if (typeof obj1[key] === 'object' && typeof obj2[key] === 'object') {
|
||||||
|
obj1[key] = Object.assign(obj1[key], obj2[key])
|
||||||
|
} else {
|
||||||
|
obj1[key] = obj2[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return obj1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get random id
|
||||||
|
*/
|
||||||
|
let seed = +new Date()
|
||||||
|
function getId() {
|
||||||
|
return ++seed
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
wrap,
|
||||||
|
transformPath,
|
||||||
|
|
||||||
|
checkFileExists,
|
||||||
|
readJson,
|
||||||
|
readFile,
|
||||||
|
writeFile,
|
||||||
|
|
||||||
|
logger,
|
||||||
|
format,
|
||||||
|
compareArray,
|
||||||
|
merge,
|
||||||
|
getId,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user