Skip to content

Commit accbe35

Browse files
committed
add mpx demo
1 parent 20daaa1 commit accbe35

24 files changed

+18918
-0
lines changed

mpx/.editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true

mpx/.eslintrc.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const { userConf } = require('./config/index')
2+
3+
const eslintConf = {
4+
root: true,
5+
parser: 'babel-eslint',
6+
parserOptions: {
7+
sourceType: 'module'
8+
},
9+
extends: 'standard',
10+
settings: {
11+
'html/html-extensions': ['.html', '.mpx'], // consider .html and .mpx files as HTML
12+
},
13+
plugins: [
14+
'html'
15+
],
16+
globals: {
17+
wx: true,
18+
getApp: true,
19+
App: true,
20+
__mpx_mode__: true
21+
},
22+
rules: {
23+
camelcase: ['error', { 'allow': ['__mpx_mode__'] }]
24+
}
25+
}
26+
if (userConf.tsSupport) {
27+
eslintConf.overrides = [
28+
{
29+
files: ['**/*.ts'],
30+
parser: '@typescript-eslint/parser',
31+
extends: [
32+
'standard',
33+
'plugin:@typescript-eslint/eslint-recommended',
34+
'plugin:@typescript-eslint/recommended',
35+
],
36+
plugins: ['@typescript-eslint'],
37+
},
38+
]
39+
}
40+
41+
module.exports = eslintConf

mpx/.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
node_modules/
3+
npm-debug.log
4+
.idea/
5+
deploy/
6+
output/
7+
dist/
8+
.vscode/

mpx/README.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# mpx
2+
3+
> A mpx project
4+
5+
## Dev
6+
7+
```bash
8+
# install dep
9+
npm i
10+
11+
# for dev
12+
npm run watch
13+
14+
# for online
15+
npm run build
16+
```
17+
18+
npm script规范 [build|watch]:[dev|prod]:[cross|web|none]
19+
20+
build默认prod,watch默认dev。另单独提供了build:dev和watch:prod,用于单次构建分析看未压缩代码分析问题和持续压缩代码便于大体积项目真机调试。
21+
22+
建议自行调整cross的目标。npm-run-all是为了兼容windows下无法同时执行两个npm script,若不需要转web平台,可考虑去掉。
23+
24+
# 关键集成步骤
25+
26+
```js
27+
import uma from 'umtrack-wx'
28+
uma.init({
29+
appKey: '5dfa09d2c1d04b48c99109a6',
30+
useOpenid: false,
31+
autoGetOpenid: false,
32+
uploadUserInfo: false,
33+
debug: true
34+
});
35+
import mpx, { createApp } from '@mpxjs/core'
36+
import apiProxy from '@mpxjs/api-proxy'
37+
mpx.use(apiProxy, { usePromise: true })
38+
createApp({
39+
onLaunch () {}
40+
},{customCtor: App});// 特别注意此处,跟微信官方的kbone类似,都是框架代码编译后优先级高于业务代码,导致无法在最开始引入sdk,无法先于框架劫持生命周期方法。需要编写特殊的webpack插件,提高友盟sdk的执行优先级。虽然mpx提供了,允许其他框架修改劫持的参数 customCtor https://mpxjs.cn/api/global-api.html#createpage ,看文档需要每个Page,Component,App实例都要注入一次,但实际用来只需要App注入该参数就能正常运行,需要进一步测试,尤其是component,避免未知问题。
41+
```

mpx/babel.config.json

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"presets": [
3+
[
4+
"@babel/env",
5+
{
6+
"modules": false,
7+
"shippedProposals": true
8+
}
9+
]
10+
],
11+
"plugins": [
12+
[
13+
"@babel/transform-runtime",
14+
{
15+
"corejs": 3,
16+
"version": "^7.10.4"
17+
}
18+
]
19+
],
20+
"env": {
21+
"test": {
22+
"presets": [
23+
[
24+
"@babel/env",
25+
{
26+
"shippedProposals": true
27+
}
28+
]
29+
]
30+
}
31+
}
32+
}

mpx/build/build.js

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
const ora = require('ora')
2+
const rm = require('rimraf')
3+
const chalk = require('chalk')
4+
const webpack = require('webpack')
5+
const program = require('commander')
6+
const { userConf, supportedModes } = require('../config/index')
7+
const getWebpackConf = require('./getWebpackConf')
8+
const { resolveDist } = require('./utils')
9+
10+
program
11+
.option('-w, --watch', 'watch mode')
12+
.option('-p, --production', 'production release')
13+
.parse(process.argv)
14+
15+
// 提供npm argv找到期望构建的平台,必须在上面支持的平台列表里
16+
const npmConfigArgvOriginal = (process.env.npm_config_argv && JSON.parse(process.env.npm_config_argv).original) || []
17+
const modeArr = npmConfigArgvOriginal.filter(item => typeof item === 'string').map(item => item.replace('--', '')).filter(item => supportedModes.includes(item))
18+
19+
// 暂时兼容npm7的写法
20+
if (!npmConfigArgvOriginal.length) {
21+
const env = process.env
22+
supportedCrossMode.forEach(key => {
23+
if (env[`npm_config_${key}`] === 'true') {
24+
modeArr.push(key)
25+
}
26+
})
27+
}
28+
29+
if (!modeArr.length) modeArr.push(userConf.srcMode)
30+
31+
let webpackConfs = []
32+
33+
modeArr.forEach((mode) => {
34+
const options = Object.assign({}, userConf, {
35+
mode,
36+
production: program.production,
37+
watch: program.watch,
38+
report: process.env.npm_config_report,
39+
subDir: (userConf.isPlugin || userConf.cloudFunc) ? 'miniprogram' : ''
40+
})
41+
webpackConfs.push(getWebpackConf(options))
42+
})
43+
44+
if (userConf.isPlugin) {
45+
const options = Object.assign({}, userConf, {
46+
plugin: true,
47+
mode: 'wx',
48+
production: program.production,
49+
watch: program.watch,
50+
report: process.env.npm_config_report,
51+
subDir: 'plugin'
52+
})
53+
webpackConfs.push(getWebpackConf(options))
54+
}
55+
56+
if (webpackConfs.length === 1) {
57+
webpackConfs = webpackConfs[0]
58+
}
59+
60+
const spinner = ora('building...')
61+
spinner.start()
62+
63+
try {
64+
modeArr.forEach(item => {
65+
rm.sync(resolveDist(item, '*'))
66+
})
67+
} catch (e) {
68+
console.error(e)
69+
console.log('\n\n删除dist文件夹遇到了一些问题,如果遇到问题请手工删除dist重来\n\n')
70+
}
71+
72+
if (program.watch) {
73+
webpack(webpackConfs).watch(undefined, callback)
74+
} else {
75+
webpack(webpackConfs, callback)
76+
}
77+
78+
function callback (err, stats) {
79+
spinner.stop()
80+
if (err) {
81+
process.exitCode = 1
82+
return console.error(err)
83+
}
84+
if (Array.isArray(stats.stats)) {
85+
stats.stats.forEach(item => {
86+
console.log(item.compilation.name + '打包结果:')
87+
process.stdout.write(item.toString({
88+
colors: true,
89+
modules: false,
90+
children: false,
91+
chunks: false,
92+
chunkModules: false,
93+
entrypoints: false
94+
}) + '\n\n')
95+
})
96+
} else {
97+
process.stdout.write(stats.toString({
98+
colors: true,
99+
modules: false,
100+
children: false,
101+
chunks: false,
102+
chunkModules: false,
103+
entrypoints: false
104+
}) + '\n\n')
105+
}
106+
107+
if (stats.hasErrors()) {
108+
console.log(chalk.red(' Build failed with errors.\n'))
109+
} else if (program.watch) {
110+
console.log(chalk.cyan(` Build complete at ${new Date()}.\n Still watching...\n`))
111+
} else {
112+
console.log(chalk.cyan(' Build complete.\n'))
113+
}
114+
}

mpx/build/getPlugins.js

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
let { mpxPluginConf, dllConf, supportedModes } = require('../config/index')
2+
const MpxWebpackPlugin = require('@mpxjs/webpack-plugin')
3+
const { resolve, resolveSrc } = require('./utils')
4+
const HtmlWebpackPlugin = require('html-webpack-plugin')
5+
const CopyWebpackPlugin = require('copy-webpack-plugin')
6+
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
7+
const VueLoaderPlugin = require('vue-loader').VueLoaderPlugin
8+
const webpack = require('webpack')
9+
const path = require('path')
10+
11+
module.exports = function getRules (options) {
12+
const { mode, srcMode, subDir, production, report } = options
13+
const plugins = []
14+
const copyIgnoreArr = supportedModes.map((item) => {
15+
return `**/${item}/**`
16+
})
17+
18+
let currentMpxPluginConf
19+
if (typeof mpxPluginConf === 'function') {
20+
currentMpxPluginConf = mpxPluginConf(options)
21+
} else {
22+
currentMpxPluginConf = mpxPluginConf
23+
}
24+
25+
plugins.push(new MpxWebpackPlugin(Object.assign({}, currentMpxPluginConf, {
26+
mode,
27+
srcMode
28+
})))
29+
const copyList = [
30+
{
31+
context: resolve(`static/${mode}`),
32+
from: '**/*',
33+
to: subDir ? '..' : ''
34+
},
35+
{
36+
context: resolve(`static`),
37+
from: '**/*',
38+
to: subDir ? '..' : '',
39+
globOptions: {
40+
ignore: copyIgnoreArr
41+
}
42+
}
43+
]
44+
45+
if (options.cloudFunc) {
46+
copyList.push({
47+
context: resolve(`src/functions`),
48+
from: '**/*',
49+
to: '../functions/'
50+
})
51+
}
52+
53+
if (options.needDll) {
54+
const getDllManifests = require('./getDllManifests')
55+
const dllManifests = getDllManifests(production)
56+
const localDllManifests = dllManifests.filter((manifest) => {
57+
return manifest.mode === mode || !manifest.mode
58+
})
59+
60+
localDllManifests.forEach((manifest) => {
61+
plugins.push(new webpack.DllReferencePlugin({
62+
context: dllConf.context,
63+
manifest: manifest.content
64+
}))
65+
copyList.push({
66+
context: path.join(dllConf.path, 'lib'),
67+
from: manifest.content.name,
68+
to: manifest.content.name
69+
})
70+
})
71+
}
72+
plugins.push(new CopyWebpackPlugin(copyList))
73+
74+
plugins.push(new webpack.DefinePlugin({
75+
'process.env': {
76+
NODE_ENV: production ? '"production"' : '"development"'
77+
}
78+
}))
79+
80+
if (mode === 'web') {
81+
plugins.push(new VueLoaderPlugin())
82+
plugins.push(new HtmlWebpackPlugin({
83+
filename: 'index.html',
84+
template: resolveSrc('index.html', subDir),
85+
inject: true
86+
}))
87+
}
88+
89+
if (report) {
90+
plugins.push(new BundleAnalyzerPlugin())
91+
}
92+
93+
return plugins
94+
}

0 commit comments

Comments
 (0)