微信小程式已經支援NPM接入,這裡指的是原汁原味的小程式開發,沒有用任何框架。今天簡單的記錄一下接入過程。
一、三個步驟
根目錄有package.json
根據 package.json 的 dependencies 欄位構建,所以宣告在 devDependencies 裡的包也可以在開發過程中被安裝使用而不會參與到構建中。如果是這之前的版本,則建議使用--production選項,可以減少安裝一些業務無關的 npm 包,從而減少整個小程式包的大小。
重點強調就是生產環境的包要放在dependencies
中!!!
根目錄有node_moudles
此處並沒有強制要求 node_modules 必須在小程式根目錄下(即 project.config.js 中的 miniprogramRoot 欄位),也可以存在於小程式根目錄下的各個子目錄中。但是不允許 node_modules 在小程式根目錄外。
重點就是你必須提前npm install
,這樣才能給小程式用。
手動執行構建NPM包
第三步就是在微信開發者工具中,手動構建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,大功告成!
記錄一下,自己第一次配webpack的經驗,踩過的坑其實都是因為經驗不足,以前瞭解的太少了,總是寫個hello word的demo就完事了。學習還是不能淺嘗擱置!!!
有問題和疑問可留言指出,文章寫得有點粗糙。