小程式接入NPM包開發實踐

yukiyang發表於2019-03-17

微信小程式已經支援NPM接入,這裡指的是原汁原味的小程式開發,沒有用任何框架。今天簡單的記錄一下接入過程。

一、三個步驟

根目錄有package.json

根據 package.json 的 dependencies 欄位構建,所以宣告在 devDependencies 裡的包也可以在開發過程中被安裝使用而不會參與到構建中。如果是這之前的版本,則建議使用--production選項,可以減少安裝一些業務無關的 npm 包,從而減少整個小程式包的大小。

重點強調就是生產環境的包要放在dependencies中!!!

根目錄有node_moudles

此處並沒有強制要求 node_modules 必須在小程式根目錄下(即 project.config.js 中的 miniprogramRoot 欄位),也可以存在於小程式根目錄下的各個子目錄中。但是不允許 node_modules 在小程式根目錄外。

重點就是你必須提前npm install,這樣才能給小程式用。

手動執行構建NPM包

小程式接入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,大功告成!

小程式接入NPM包開發實踐

記錄一下,自己第一次配webpack的經驗,踩過的坑其實都是因為經驗不足,以前瞭解的太少了,總是寫個hello word的demo就完事了。學習還是不能淺嘗擱置!!!

有問題和疑問可留言指出,文章寫得有點粗糙。

相關文章