# 使用npm
Mpx项目中用户能够方便自然地引用 npm 资源,像 web 开发中一样
在 Mpx 中使用 npm,通过 Webpack 插件在编译时将引用的 npm 包输出为小程序文件,所以 Mpx 的构建产物不需要在开发工具再次进行 npm 构建。
# 下载npm包
在项目 package.json 所在的目录中执行命令安装项目 npm 包
npm install
在项目中安装某个第三方 npm 包
npm install mpx-ui
如若之前未接触过 npm,请翻阅 官方 npm 文档 (opens new window) 进行学习。
# 引用npm模块
直接使用模块路径引用,可以直接通过 ES6 的 import 语法来引用 JS 文件,并且无需额外执行npm构建
import { createPage } from '@mpxjs/core'
# 引用npm组件/页面
在页面 script 标签中的 json 对象中使用 usingComponents 引入第三方组件,直接使用模块路径引用
<script type="application/json">
{
"usingComponents": {
"mpx-button": "mpx-ui/src/components/button"
}
}
</script>
在 app.mpx 中的 script 标签中的 pages/packages/subPackages 中都可以声明引用 npm 包页面
示例:
<script type="application/json">
{
"pages": [
"@someGroup/someNpmPackage/pages/view/index.mpx"
]
}
</script>
以上这种写法为避免和本地页面路径冲突,Mpx 会将路径进行 hash 化处理,所以使用页面时要在路径后添加 ?resovle 标识符,编译时会被处理成正确的、完整的绝对路径。
import packageIndexPage from '@someGroup/someNpmPackage/pages/view/index.mpx?resolve'
mpx.navigateTo({
url: packageIndexPage
})
如果你觉得上述引用 npm 包页面的方式太繁琐,我们也提供了另一种 page 声明方式,可以让你自定义页面路径
// 声明
{
"pages": [
{
"src": "@someGroup/someNpmPackage/pages/view/index.mpx",
"path": "pages/somNpmPackage/index" // 注意保持 path 的唯一性
}
]
}
// 使用
// 可以直接使用你自己声明的 path
mpx.navigateTo({
url: '/pages/somNpmPackage/index'
})
同理,我们在使用 subPackages 分包时也可以使用 pages 对象的方式
"subPackages": [
{
"root": "test",
"pages": [
{
"src": "@someGroup/someNpmPackage/pages/view/index.mpx",
"path": "pages/somNpmPackage/index" // 注意保持 path 的唯一性
}
]
}
]
// 使用
mpx.navigateTo({
url: '/test/pages/somNpmPackage/index'
})
同时使用 Mpx 引用npm组件/页面时包体积比原生中的 npm 规范更优,好处有:
Mpx npm构建的优势主要有两点:1. 按需构建;2. 支持分包
小程序的 npm 规范场景下,组件库需声明miniprogram_dist目录,执行构建npm命令,将整个miniprogram_dist中的代码copy到项目的miniprogram_npm目录下。而 Mpx 的 npm 包引用,借助 Webpack 强大的构建分析能力,loader 在解析 json 中的 pages 域和 usingComponents 域中的路径时,通过动态创建 entry 的方式把这些文件添加进来,同时按需加载被确切使用的文件,降低包体积,借助 CommonsChunkPlugin/SplitChunksPlugin 的能力将复用的 js 模块抽出到一个外部公用的 bundle 中。
原生小程序的构建中,所有的 npm 模块都会输出到主包中,Mpx 在编译中,还会进行分包处理,对组件和静态资源,根据用户的分包配置,串行对主包和各个分包进行构建,标记出每个组件及静态资源的归属,根据小程序资源访问策略将其输出到主包或者分包中。
所以使用 Mpx 框架开发小程序,可以享受最舒适最自然最好用的 npm 机制,详细原理介绍请移步Mpx编译构建原理
# 兼容原生小程序路径规范
组件或者页面的引入有绝对路径和相对路径,或者引入 npm 第三方包,原生小程序中,我们通过相对路径引入一个组件时
{
"usingComponents": {
"component-tag-name": "path/to/the/custom/component"
}
}
这种路径形式在 webpack 路径规范中会被当成 npm 包路径来处理,所以要对原生小程序的路径规范做下兼容。
Mpx 提供了两种路径规范的配置模式可供大家选择,具体的使用方式为:
// vue.config.js
module.exports = defineConfig({
pluginOptions: {
mpx: {
plugin: {
resolveMode: 'webpack'
}
}
}
})
在 MpxWebpackPlugin 插件中设置 resolveMode 项,默认值为 webpack,可选值有 webpack/native,推荐使用 webpack 模式,更舒服一些,配置项为 webpack 时,json 中的 pages/usingComponents 等需要写相对路径,但是也可以直接写 npm 包路径。例如:
{
"usingComponents": {
"component-tag-name": "./path/to/the/custom/component", // 内部组件路径
"mpx-button": "mpx-ui/src/components/button" // npm 包路径
}
}
如果希望使用类似小程序原始那种"绝对路径",可以将 resolveMode 设置为 native,但是 npm 路径需要在前面加一个~,类似 webpack 的样式引入规范,同时必须配合 projectRoot 参数提供项目根目录地址。
resolveMode 为 native 时的使用示例:
// vue.config.js
module.exports = defineConfig({
pluginOptions: {
mpx: {
plugin: {
resolveMode: 'native',
// 当resolveMode为native时可通过该字段指定项目根目录
projectRoot: path.resolve(__dirname, '../src')
}
}
}
})
// 项目page.mpx
{
"usingComponents": {
"mpx-button": "~mpx-ui/src/components/button", // npm 包路径
"component-tag-name": "path/to/the/custom/component" // 内部组件路径
}
}