Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ npm run build
```

> RN项目不支持pnpm,请在创建输出到RN项目时指定 mpx create -m npm 来创建项目
>
> @achrinza/node-ipc包在engine-strict模式下不兼容node23,可映射到修复包node-ipc-compat@1.0.0,针对不同包管理器(pnpm/npm)在package.json中添加如下对应代码,我们已自动化处理,无需手动添加。
> ```json
> "pnpm": {
> "overrides": {
> "@achrinza/node-ipc": "npm:node-ipc-compat@1.0.0"
> }
> },
> "overrides": {
> "@achrinza/node-ipc": "npm:node-ipc-compat@1.0.0"
> }
> ```

#### build

Expand Down
34 changes: 33 additions & 1 deletion packages/mpx-cli/lib/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ const {
exit,
error,
log,
stopSpinner
stopSpinner,
hasYarn,
hasPnpm3OrLater
} = require('@vue/cli-shared-utils')
const { loadOptions } = require('@vue/cli/lib/options')
const Creator = require('@vue/cli/lib/Creator')
const loadRemotePreset = require('@vue/cli/lib/util/loadRemotePreset')
const loadLocalPreset = require('@vue/cli/lib/util/loadLocalPreset')
Expand Down Expand Up @@ -176,6 +179,35 @@ async function create (projectName, options, preset = null) {

const creator = new Creator(name, targetDir, getPromptModules())

const packageManager =
options.packageManager ||
loadOptions().packageManager ||
(hasYarn() ? 'yarn' : null) ||
(hasPnpm3OrLater() ? 'pnpm' : 'npm')

// @achrinza/node-ipc与node23不兼容,需要映射到修复包node-ipc-compat@1.0.0
creator.on('creation', ({ event }) => {
if (event === 'plugins-install' || event === 'deps-install') {
try {
const pkgPath = path.resolve(targetDir, 'package.json')
const pkg = fs.readJsonSync(pkgPath)
// 根据包管理器类型写入对应的 overrides 配置,yarn无需处理
if (packageManager === 'pnpm') {
pkg.pnpm = {
overrides: {
'@achrinza/node-ipc': 'npm:node-ipc-compat@1.0.0'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

grep -r "node-ipc-compat" --include="*.js" --include="*.json" .

Repository: mpx-ecology/mpx-cli

Length of output: 351


The package node-ipc-compat@1.0.0 does not exist on the NPM registry and will cause installation to fail.

The hardcoded alias to npm:node-ipc-compat@1.0.0 cannot be resolved. Web searches show no published package by this name or version. Similar alternatives like @node-ipc/compat (version 9.2.5) exist but not the referenced package. This dependency must be corrected before the code can be used in production, as any package installation will fail with a resolution error.

🤖 Prompt for AI Agents
In packages/mpx-cli/lib/create.js around line 198 the dependency alias
'@achrinza/node-ipc': 'npm:node-ipc-compat@1.0.0' points to a non-existent
package and will break installs; replace it with a valid package/version (for
example use the published @node-ipc/compat with a concrete version like 9.2.5 or
remove the alias and reference the correct package name directly), update the
lock/manifest if present, and verify by running an install to ensure the package
resolves from the NPM registry.

}
}
} else if (packageManager === 'npm') {
pkg.overrides = {
'@achrinza/node-ipc': 'npm:node-ipc-compat@1.0.0'
}
}
fs.writeJsonSync(pkgPath, pkg, { spaces: 2 })
} catch (e) {}
}
})
Comment on lines +189 to +209
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Risk of overwriting existing pnpm/npm configurations.

The code completely replaces pkg.pnpm and pkg.overrides objects, which could delete any existing configurations users may have. This is especially problematic if other CLI plugins or user customizations have already added pnpm or npm overrides.

🔎 Proposed fix to merge instead of replace
         // 根据包管理器类型写入对应的 overrides 配置,yarn无需处理
         if (packageManager === 'pnpm') {
-          pkg.pnpm = {
-            overrides: {
-              '@achrinza/node-ipc': 'npm:node-ipc-compat@1.0.0'
-            }
-          }
+          pkg.pnpm = pkg.pnpm || {}
+          pkg.pnpm.overrides = pkg.pnpm.overrides || {}
+          pkg.pnpm.overrides['@achrinza/node-ipc'] = 'npm:node-ipc-compat@1.0.0'
         } else if (packageManager === 'npm') {
-          pkg.overrides = {
-            '@achrinza/node-ipc': 'npm:node-ipc-compat@1.0.0'
-          }
+          pkg.overrides = pkg.overrides || {}
+          pkg.overrides['@achrinza/node-ipc'] = 'npm:node-ipc-compat@1.0.0'
         }
🤖 Prompt for AI Agents
In packages/mpx-cli/lib/create.js around lines 189 to 209, the code currently
replaces pkg.pnpm and pkg.overrides wholesale which can wipe out existing user
or plugin configurations; instead, read package.json (already done), ensure the
pnpm and overrides objects exist, and merge the new entry into the existing
objects (perform a shallow merge for pkg.pnpm and pkg.overrides, and
specifically merge into pkg.pnpm.overrides if using pnpm) rather than assigning
a new object; create the objects if missing, preserve existing keys, then write
the merged pkg back; also keep the try/catch but consider logging the error
instead of swallowing it.


if (process.env.VUE_CLI_TEST || process.env.VUE_CLI_DEBUG) {
// 单测下,link bin文件到源码
const { linkBin } = require('@vue/cli/lib/util/linkBin')
Expand Down
6 changes: 3 additions & 3 deletions packages/vue-cli-plugin-mpx-ssr/commands/build/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
const { normalizeCommandArgs } = require('@mpxjs/cli-shared-utils')
const { normalizeCommandArgs, getCurrentTarget } = require('@mpxjs/cli-shared-utils')
const { addBaseWebpackConfig } = require('../../config/base.config')
const { addBuildWebpackConfig } = require('../../config/build.config')
const { resolveBuildWebpackConfigByTarget } = require('@mpxjs/vue-cli-plugin-mpx/config')
const { getCurrentTarget } = require('@mpxjs/cli-shared-utils')
const { handleWebpackDone } = require('@mpxjs/vue-cli-plugin-mpx/utils/webpack')
const webpack = require('webpack')
const fs = require('fs-extra')
Expand Down Expand Up @@ -42,7 +41,8 @@ module.exports.registerBuildCommand = function (api, options) {
const { webpackConfig, target } = await getBaseConfig(ssrMode)
return new Promise((resolve, reject) => {
webpack(webpackConfig, (err, stats) => {
handleWebpackDone(err, stats, target, api)
// todo:此处target应该是一个布尔值,判断是否watch, 直接把target和api替换掉有问题嘛,当前只将api换为了options
handleWebpackDone(err, stats, target, options)
Comment on lines +44 to +45
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Incorrect parameter type passed to handleWebpackDone.

The third parameter of handleWebpackDone(err, stats, watch, options) expects a boolean indicating watch mode, but target (a platform identifier string like 'wx', 'ali', etc.) is being passed instead. This will cause incorrect behavior in the webpack completion handler.

For build commands, the watch parameter should typically be:

  • false (for standard builds), or
  • args.watch (if watch mode is supported via CLI args)
🔎 Proposed fix
-            // todo:此处target应该是一个布尔值,判断是否watch, 直接把target和api替换掉有问题嘛,当前只将api换为了options
-            handleWebpackDone(err, stats, target, options)
+            handleWebpackDone(err, stats, false, options)

Or if watch mode should be supported:

-            // todo:此处target应该是一个布尔值,判断是否watch, 直接把target和api替换掉有问题嘛,当前只将api换为了options
-            handleWebpackDone(err, stats, target, options)
+            handleWebpackDone(err, stats, args.watch || false, options)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// todo:此处target应该是一个布尔值,判断是否watch, 直接把target和api替换掉有问题嘛,当前只将api换为了options
handleWebpackDone(err, stats, target, options)
handleWebpackDone(err, stats, false, options)
🤖 Prompt for AI Agents
In packages/vue-cli-plugin-mpx-ssr/commands/build/index.js around lines 44-45,
the third argument passed to handleWebpackDone is currently `target` (a platform
string) but the function expects a boolean `watch`; change the call so the third
parameter is a boolean: for standard builds pass `false`, or if CLI watch
support exists pass `Boolean(args.watch)` (or `args.watch` directly) instead of
`target`, and ensure the `options` argument remains the last parameter.

.then((...res) => {
resolve(...res)
})
Expand Down
2 changes: 1 addition & 1 deletion packages/vue-cli-plugin-mpx/commands/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ module.exports.registerBuildCommand = function (api, options) {
await api.runAfterResolveWebpackCallBack(webpackConfig)
return new Promise((resolve, reject) => {
webpack(webpackConfig, (err, stats) => {
handleWebpackDone(err, stats, args.watch)
handleWebpackDone(err, stats, args.watch, options)
.then((...res) => {
if (target !== 'web' && !options.disabledDefaultLinkFile) {
// web版本不需要symlink
Expand Down
2 changes: 1 addition & 1 deletion packages/vue-cli-plugin-mpx/commands/serve/mp.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports.serveMp = async function serveMp (api, options, args) {
// 运行webpack
return new Promise((resolve, reject) => {
webpack(webpackConfigs).watch({}, (err, stats) => {
handleWebpackDone(err, stats, true)
handleWebpackDone(err, stats, true, options)
.then((...res) => {
if (!options.disabledDefaultLinkFile) {
symlinkTargetConfig(api, target, webpackConfigs[0])
Expand Down
3 changes: 2 additions & 1 deletion packages/vue-cli-plugin-mpx/commands/serve/web.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ module.exports.serveWeb = async (api, options, args) => {
}

result.push('', extractResultFromStats(stats, {
assets: false
assets: false,
...(options.pluginOptions?.mpx?.stats || {})
}))

getReporter()._renderStates([
Expand Down
4 changes: 2 additions & 2 deletions packages/vue-cli-plugin-mpx/config/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ function addWebWebpackConfig (api, options, config, target) {
.rule('mpx')
.test(/\.mpx$/)
.use('vue-loader')
.loader(require.resolve('@vue/vue-loader-v15'))
.loader(require('module').Module.createRequire(require.resolve('@vue/cli-service')).resolve('@vue/vue-loader-v15'))
.end()
.use('mpx-loader')
.loader(require.resolve(mpxLoader.loader))
Expand Down Expand Up @@ -472,7 +472,7 @@ module.exports.addBaseConfig = function (api, options, config, target) {

config.resolve.modules.add('node_modules')

const dependenciesConfig = [api.resolve('vue.config.js')]
const dependenciesConfig = [api.resolve('mpx.config.js')]

const addDepConfig = (names = []) => {
names.forEach((name) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
const autoprefixer = require('autoprefixer')
const RN = ['android', 'ios', 'harmony']
const isRN = RN.includes(
process.env.MPX_CURRENT_TARGET_MODE
)
// RN环境下去除postcss的autoprefix插件
module.exports = {
plugins: [
require('autoprefixer')({ remove: false })
]
}
!isRN && autoprefixer({ remove: false })
].filter(Boolean)
}
2 changes: 1 addition & 1 deletion packages/vue-cli-plugin-mpx/utils/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function extractResultFromStats (stats, options = {}) {
return item
.toString({
assets: true,
colors: true,
colors: !process.env.CI,
modules: false,
children: false,
chunks: false,
Expand Down
5 changes: 3 additions & 2 deletions packages/vue-cli-plugin-mpx/utils/webpack.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { getReporter, getLogUpdate } = require('./reporter')
const { extractResultFromStats } = require('./output')

function handleWebpackDone (err, stats, watch) {
function handleWebpackDone (err, stats, watch, options = {}) {
const statsOptions = options.pluginOptions?.mpx?.stats || {}
return new Promise((resolve, reject) => {
if (err) return reject(err)
const hasErrors = stats.hasErrors()
Expand All @@ -19,7 +20,7 @@ function handleWebpackDone (err, stats, watch) {
color: hasErrors ? 'red' : 'green',
progress: 100,
hasErrors: hasErrors,
result: extractResultFromStats(v).join('\n')
result: extractResultFromStats(v, statsOptions).join('\n')
}
}),
() => {
Expand Down