原汁原味的配方:「微信小程序支持 NPM」

歡迎來我的博客閱讀:「原汁原味的配方:「微信小程序支持 NPM」

微信小程序本身不支持 npm 包的使用,目前市面上很多框架也有了相對應的解決方案累铅。

本文旨在為那些不愿意引入第三方框架糕非, 想在小程序環(huán)境中寫原汁原味代碼的人(例如我)蒙具,提供一種解決問題的思路。

在現(xiàn)代的 Web 開發(fā)中朽肥,我們對 Webpack 已經(jīng)再熟悉不過了禁筏,簡單理解,它就是項目發(fā)布之前衡招,把所有資源都打包好篱昔,然后提供一個入口文件,在入口模板中引入這個入口文件。

那么我的思路州刽,就是利用 Webpack 把我們所有的 npm 依賴打包好空执,提供一個入口文件,在小程序開發(fā)中穗椅,我們通過這個入口文件辨绊,進而使用 npm 的依賴。

image

我們最終實現(xiàn)的效果應該是這樣的房待。

例如我們小程序的首頁中邢羔,需要使用到 moment

pages/home/home.js:

const { moment } require('../npm/index');
const time = moment();

Webpack 打包 npm 依賴

webpack 默認輸出的 bundle.js ,是一個立即執(zhí)行的閉包桑孩,如以下:

使用 webpack.config.js 配置:

const path = require('path');

module.exports = {
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
};

運行 $ webpack 生成的 bundle.js :

(function(modules) { 

  // webpackBootstrap

})([module1, module2, module3]);

示例代碼:https://github.com/JerryC8080/use-npm-in-weapp/tree/master/step1

這樣的代碼拜鹤,顯然沒法達到我們要的效果。
幸好 webpack 提供了 output.libraryTarget 的配置項流椒。

output.libraryTarget: "commonjs2"

對于 output.libraryTarget: "commonjs2" 官方解釋:

The return value of your entry point will be assigned to the module.exports.

通過配置該屬性敏簿,我們能保證 webpack 打包出來的 bundle.js,是模塊化的宣虾。
當然 output.libraryTarget 還有其他的選項值惯裕,可以查閱官方文檔

例如绣硝,使用 webpack.config.js 配置:

const path = require('path');

module.exports = {
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    libraryTarget: 'commonjs2',
  }
};

運行 $ webpack 生成的 bundle.js :

module.exports = (function(modules) { 

  // webpackBootstrap

})([module1, module2, module3]);

示例代碼:https://github.com/JerryC8080/use-npm-in-weapp/tree/master/step2

這樣蜻势,我們就可以通過 require('bundle.js'), 來使用 npm 依賴了。
在這個基礎(chǔ)上鹉胖,我們就可以打造一個使用 npm 依賴的入口握玛。

打造 npm 入口

建立入口文件:npm.js

const momennt = require('moment');

module.exports = {
    momennt,
};

配置文件:webpack.config.js

const path = require('path');

module.exports = {
    entry: './entry.js',
    output: {
        path: path.resolve(__dirname, 'npm'),
        filename: 'index.js'
    },
};

運行 $ webpack,輸出 ./npm/index.js 打包文件甫菠,對應的目錄:

.
├── entry.js
├── npm
│   └── index.js
└── webpack.config.js

示例代碼:https://github.com/JerryC8080/use-npm-in-weapp/tree/master/step3

笨拙點的方法挠铲,你只需要把 npm/index.js 拷貝到你的項目中,就可以使用你所引入的 npm 包的內(nèi)容了寂诱。

如果你的項目中使用了構(gòu)建工具的話拂苹,就可以把「 webpack 打包 npm」 的這項任務加入到你的構(gòu)建流程中。

我是使用 gulp 來做項目構(gòu)建工作的痰洒,下面提供一種基于 gulp 的實現(xiàn)作為參考瓢棒。

結(jié)合 Gulp 做項目工程化

工程目錄:

.
├── dist
│   ├── npm
│   │   └── index.js
│   └── pages
│       └── home
│           └── home.js
├── gulpfile.js
└── src
    ├── npm
    │   └── index.js
    └── pages
        └── home
            └── home.js

而 gulpfile 負責兩件事:

  1. 把 src 的 js 文件通過 babel 編譯到 dist 目錄(示例中忽略其他 wxml、wxss 文件)
  2. npm/index.js 通過 webpack 打包到 dist/npm/index.js丘喻,并壓縮音羞。

gulpfile.js:

const gulp = require('gulp');
const babel = require('gulp-babel');
const del = require('del');
const runSequence = require('run-sequence');
const webpack = require('webpack');
const webpackStream = require('webpack-stream');

const webpackConfig = {
    module: {
        loaders: [{
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: {
                presets: ['es2015'],
            },
        }],
    },
    output: {
        filename: 'index.js',
        libraryTarget: 'commonjs2',        
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin(),
    ],
};

// 清空 ./dist 目錄
gulp.task('clean', () => del(['./dist/**']));

// 打包 npm 依賴
gulp.task('npm', () => {
    gulp.src('./src/npm/*.js')
        .pipe(webpackStream(webpackConfig), webpack)
        .pipe(gulp.dest('./dist/npm'));
});

// 編譯 JS 文件
gulp.task('scripts', () => {
    gulp.src(['./src/**/*.js', '!./src/npm/*.js'])
        .pipe(babel({
            presets: ['stage-0', 'es2015'],
        }))
        .pipe(gulp.dest('./dist'));
});

// 開發(fā)模式命令
gulp.task('build', ['clean'], () => runSequence('scripts', 'npm'));

示例代碼:https://github.com/JerryC8080/use-npm-in-weapp/tree/master/step4

關(guān)于控制 npm 文件代碼量

微信限制了項目的代碼量為 2M,就算使用了分包機制仓犬,最多也是 4M 的代碼量嗅绰。
區(qū)區(qū)一個 moment 庫的話,就算壓縮過,也需要兩百多 KB窘面,這對于我們的代碼量翠语,是很不友好的。
我們需要對 npm 的引入持非常謹慎的態(tài)度财边,去度量每個依賴包的大小肌括,想盡各種辦法減少依賴的代碼量。
譬如moment 我們可以使用 moment-mini 來代替酣难,后者壓縮過后只需要 51KB谍夭。

而且我認為把 npm 的依賴放在一個入口文件中,會讓我們可以對 npm 的依賴有一個全局的把握憨募。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末紧索,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子菜谣,更是在濱河造成了極大的恐慌珠漂,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尾膊,死亡現(xiàn)場離奇詭異媳危,居然都是意外死亡,警方通過查閱死者的電腦和手機冈敛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門待笑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人抓谴,你說我怎么就攤上這事暮蹂。” “怎么了齐邦?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵椎侠,是天一觀的道長第租。 經(jīng)常有香客問我措拇,道長,這世上最難降的妖魔是什么慎宾? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任丐吓,我火速辦了婚禮,結(jié)果婚禮上趟据,老公的妹妹穿的比我還像新娘券犁。我一直安慰自己,他們只是感情好汹碱,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布粘衬。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稚新。 梳的紋絲不亂的頭發(fā)上勘伺,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機與錄音褂删,去河邊找鬼飞醉。 笑死,一個胖子當著我的面吹牛屯阀,可吹牛的內(nèi)容都是我干的缅帘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼难衰,長吁一口氣:“原來是場噩夢啊……” “哼钦无!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起召衔,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤铃诬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后苍凛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趣席,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年醇蝴,在試婚紗的時候發(fā)現(xiàn)自己被綠了宣肚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡悠栓,死狀恐怖霉涨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惭适,我是刑警寧澤笙瑟,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站癞志,受9級特大地震影響往枷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凄杯,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一错洁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧戒突,春花似錦屯碴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忱叭。三九已至,卻和暖如春今艺,著一層夾襖步出監(jiān)牢的瞬間窑多,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工洼滚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留埂息,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓遥巴,卻偏偏與公主長得像千康,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子铲掐,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容

  • GitChat技術(shù)雜談 前言 本文較長拾弃,為了節(jié)省你的閱讀時間,在文前列寫作思路如下: 什么是 webpack摆霉,它要...
    蕭玄辭閱讀 12,697評論 7 110
  • 最近在學習 Webpack,網(wǎng)上大多數(shù)入門教程都是基于 Webpack 1.x 版本的,我學習 Webpack 的...
    My_Oh_My閱讀 8,184評論 40 247
  • 在現(xiàn)在的前端開發(fā)中豪椿,前后端分離、模塊化開發(fā)携栋、版本控制搭盾、文件合并與壓縮、mock數(shù)據(jù)等等一些原本后端的思想開始...
    Charlot閱讀 5,443評論 1 32
  • 一婉支、webpack的基本概念 webpack 本質(zhì)上是一個打包工具鸯隅,它會根據(jù)代碼的內(nèi)容解析模塊依賴,幫助我們把多個...
    cilla123閱讀 1,543評論 0 8
  • 迎夏花為木犀科向挖,又稱為探春花蝌以,為木犀科素馨屬的植物,春末夏初何之,花滿梢頭跟畅,為中國的特有植物。與同屬植物迎春比較相像溶推,...
    王了一一閱讀 4,514評論 19 13