小程序接入NPM包开发实践
微信小程序已经支持NPM接入,这里指的是原汁原味的小程序开发,没有用任何框架。今天简单的记录一下接入过程。
一、三个步骤
根目录有package.json
根据 package.json 的 dependencies 字段构建,所以声明在 devDependencies 里的包也可以在开发过程中被安装使用而不会参与到构建中。如果是这之前的版本,则建议使用--production选项,可以减少安装一些业务无关的 npm 包,从而减少整个小程序包的大小。
重点强调就是生产环境的包要放在dependencies
中!!!
根目录有node_moudles
此处并没有强制要求 node_modules 必须在小程序根目录下(即 project.config.js 中的 miniprogramRoot 字段),也可以存在于小程序根目录下的各个子目录中。但是不允许 node_modules 在小程序根目录外。
重点就是你必须提前npm install
,这样才能给小程序用。
手动执行构建NPM包
image第三步就是在微信开发者工具中,手动构建NPM。需要保证前两个步骤做完了哦。这个步骤其实就是小程序重新整理了一下
node_moudles
包,构建出来一个miniprogram_npm
文件,其实里面放的才是我们npm执行过程真正引用的包。可以理解为小程序版本的node_moudles
。
二、开发NPM包
小程序的NPM包与普通NPM包的区别不大,小小的区别就是,需要在package.json
中增加一个参数miniprogram
。参数指定的名字,比如说是dist
,那么在上述的手动执行构建NPM包的过程中,小程序就会把npm包中dist的目录给构建一下。
官方文档: 构建过程中,小程序 npm 包会直接拷贝构建文件生成目录下的所有文件到 miniprogram_npm 中。
其实也就dist目录。dist目录要求是构建文件,也就是说需要我们自己进行构建~ 这里我选择了webpack进行构建。
三、webpack构建小程序自定义组件NPM包
NPM包开发除了纯js包,其他的就是自定义组件(也就是component)。
自定义组件自定义组件常见的格式,不知道可以看下下文档~
在公司做项目,都是在别人搭好的架子上开发。以至于自己使用WebPack的时候感觉真的懂得好少。悲伤/(ㄒoㄒ)/~~
这里遇到的最大的坑就是,一般我们就传入给WebPack一个入口js文件,再把css分离出来即可。但是小程序的css和js是没有引用关系的。因此采用了多入口的配置项。并把json和wxml文件拷贝到dist
目录中。
引入依赖
这里有2个插件需要说明一下,ExtractTextPlugin
用于分离css,CopyWebpackPlugin
用来拷贝文件。
'use strict';
const fs = require('fs');
const path = require('path');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ENTRY_DIR = path.resolve('./src');
const isBuild = process.env.WEBPACK_ENV === 'build';
处理入口文件
因为js不引用less,所以需要单独对less进行处理。
同时还有wxml、json等文件需要拷贝到dist目录中。
// 处理入口文件
let entryObj = {};
let entryLessObj = {};
let copyArr = [];
let handleEntryObj = (dir) => {
let files = fs.readdirSync(dir);
files.forEach((fileName) => {
let isFile = fs.statSync(path.join(dir, fileName)).isFile();
let filePath = `${dir}/${fileName}`;
if (!isFile) {
// 目录
handleEntryObj(filePath);
} else if (/\.js$/i.test(fileName)) {
// 处理js
entryObj[filePath.replace(`${ENTRY_DIR}/`, '')
.replace(/\.js$/i, '')] = filePath;
} else if (/\.less$/i.test(fileName)) {
// 处理 less
entryLessObj[filePath.replace(`${ENTRY_DIR}/`, '')
.replace(/\.less$/i, '')] = filePath;
} else {
// 其他文件拷贝处理
copyArr.push({
from: filePath,
to: `${path.resolve(__dirname, 'dist')}${filePath.replace(`${ENTRY_DIR}`, '')}`,
});
}
});
};
handleEntryObj(ENTRY_DIR);
多入口配置
这里就是多入口配置,自己最开始一直用一个入口,打包出来的文件一直都有问题。
// 配置项 js & less
const config = [
// js 配置
{
entry: entryObj,
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [
{
test: /\.json$/,
loader: 'json-loader',
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.js$/,
loader: 'eslint-loader',
exclude: /node_modules/,
},
],
},
},
// less 配置
{
entry: entryLessObj,
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].wxss',
},
module: {
rules: [
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
minimize: !!isBuild,
}
},
"less-loader",
]
})
},
],
},
plugins: [
new ExtractTextPlugin('[name].wxss'),
new CopyWebpackPlugin(copyArr),
],
},
];
module.exports = config;
执行webpack,大功告成!
image
记录一下,自己第一次配webpack的经验,踩过的坑其实都是因为经验不足,以前了解的太少了,总是写个hello word的demo就完事了。学习还是不能浅尝搁置!!!
有问题和疑问可留言指出,文章写得有点粗糙。