微信小程式之程式碼構建初探:如何繼續使用html與css開發小程式

這波能反殺發表於2019-03-03

微信小程式似乎會給網際網路帶來一場非比尋常的變革。隨處可見關於小程式的文章也讓我們感受到它正在颳起一陣風暴,所以呢,抽空研究研究它,還是非常有必要的,加上最近小程式公測,通過註冊未認證的小程式,我們可以得到一個appid,下載最新的開發工具,就可以開始嘗試編寫一些demo了。

但是在開發小程式的時候,由於我們比較常用的編輯器對於.wxml, .wxss字尾的檔案並沒有多少支援,目前我所知道的,除了vs code有一個叫做vs wxml的外掛之外,幾乎沒有其他外掛了,因此,沒有程式碼補全,沒有emmet支援,沒有程式碼高亮,這極大的影響了開發效率,我也知道有很多來嘗試小程式開發的同學為此而非常困擾。

好在,辦法總是有的。

大家都知道大多數編輯器對於html與css的支援非常全面完善,特別是emmet外掛,對於html和css來說,已經變得必不可少了。而微信的wxml與wxss其實與html與css差別並不大。因此,我們只需要在開發時,將程式碼寫在html與css中,在儲存時,通過構建工具,將檔案的字尾名改成.wxml與.wxss即可。這樣一來,我們就不用在內建工具中開發,不用到處找對於小程式支援良好的IDE,也不用等各位大佬出新的外掛了,就用我們各自最喜歡最熟悉的編輯器就可以。下面我以我最熟悉的gulp為例,與大家分享一下具體如何實現。

準備

我們知道小程式的頁面都在pages資料夾下,首先建立一個demo資料夾,這裡將會放置我們的新頁面,並在demo資料夾裡建立一個dev資料夾,用於存放html與css檔案,大概的目錄結構如下

// + 表示資料夾   - 表示檔案
+ pages
  + demo
    + dev
      + html
        - demo.html
        - demo2.html
      + styles
        - demo.scss
        - _reset.scss
        - _libs.scss
      + scripts
        - demo.js複製程式碼

因為在平時開發中,常常將scss編譯為css使用,因此這裡我們也用scss來進行開發

編譯之後,得到的結構大約如下

+ pages
  + demo
    + dev
    - demo.wxml
    - demo.wxss
    - demo.js
    - gulpfile.js複製程式碼

我們的目的,就是將dev中的html,js,scss,通過gulp,編譯成為小程式能夠支援的wxml,js與wxss,在清楚了目的之後,我們就來新增gulp任務就行了。

首先在gulpfile.js中定義一個路徑物件,以方便後續的使用

// 設定相關路徑
var paths = {
    wxml: `html`,
    wxss: `styles`,
    js: `scripts`,
    img: `images`
};複製程式碼

具體要使用那些gulp外掛,大家在使用的時候根據提示安裝即可,因為是根據之前的老檔案修改,比較懶沒有去區分具體使用了那些外掛,見諒。

HTML

對於html的處理比較簡單,只有2個操作,修改字尾名與在你希望的位置生成新的wxml檔案

gulp.task(`wxml`, function() {
    var src = [paths.wxml + `/**/*.html`];
    return gulp.src(src)
        .pipe(plumber({
            errorHandler: handleError
        }))
        .pipe(foreach(function(stream, file) {
            return stream.pipe(rename(file.relative.replace(/.html/gi, `.wxml`)));
        }))
        .pipe(gulp.dest(`../`))
        .pipe(notify({
            onLast: true,
            message: "transform wxml success!"
        }));
});複製程式碼

JS

js就更簡單了,由於開發工具自己內建了編譯方式,我們只需要按照commonJs的方式處理自己的程式碼就行,不需要進行額外的處理,但是為了統一,也將開發程式碼放在dev檔案中,編譯時在你想要的位置重新生成即可

gulp.task(`wxjs`, function() {
    var src = [paths.js + `/**/*.js`];
    return gulp.src(src)
        .pipe(plumber({
            errorHandler: handleError
        }))
        .pipe(gulp.dest(`../`))
        .pipe(notify({
            onLast: true,
            message: "transform wxjs success!"
        }))
});複製程式碼

SCSS

對於scss的處理工作稍微要多一點,我們的主要目的是要繼續使用scss的語法與特性,並最終編譯成.wxss檔案

gulp.task(`wxss`, function() {
    var src = [paths.wxss + `/**/*!(_).scss`];
    return gulp.src(src)
        .pipe(plumber({
            errorHandler: handleError
        }))
        .pipe(foreach(function(stream, file) {
            return stream
                .pipe(path.extname(file.relative) == `.less` ? less() : sass().on(`error`, sass.logError));
        }))
        .pipe(csscomb())
        .pipe(minifycss({
            aggressiveMerging: false,
            advanced: false,
            compatibility: `ie7`,
            keepBreaks: true
        }))
        .pipe(cssbeautify({
            autosemicolon: true
        }))
        .pipe(foreach(function(stream, file) {
            return stream.pipe(rename(file.relative.replace(/.css/gi, `.wxss`)));
        }))
        .pipe(gulp.dest(`../`))
        .pipe(notify({
            onLast: true,
            message: "browser reload for css"
        }));
});複製程式碼

ok,這樣就大功告成了,熟悉gulp的同學可以動手嘗試一下了,熟悉其他構建工具的同學也可以根據我提供的思路實現同樣的效果。想來也是不難的。當然,這只是程式碼構建的一些小的嘗試,當面臨具體專案時,還需要更多更嚴謹的考慮才行。

完整程式碼

`use strict`;

var rf = require("fs");
var path = require("path");
var through = require("through2");
var gulp = require(`gulp`);
var concat = require(`gulp-concat`);
var uglify = require(`gulp-uglify`);
var del = require(`del`);
var gutil = require(`gulp-util`);
var less = require(`gulp-less`);
var minifycss = require(`gulp-minify-css`);
var autoprefixer = require(`gulp-autoprefixer`);
var csscomb = require(`gulp-csscomb`);
var cssbeautify = require(`gulp-cssbeautify`);
var rename = require(`gulp-rename`);
var changed = require(`gulp-changed`);
var header = require(`gulp-header`);
var footer = require(`gulp-footer`);
var livereload = require(`gulp-livereload`);
var watch = require(`gulp-watch`);
var imgcache = require(`gulp-imgcache`);
var notify = require("gulp-notify");
var foreach = require("gulp-foreach");
var sass = require("gulp-sass");
var sort = require(`gulp-sort`);
var replace = require(`gulp-replace`);

// 影像處理
var imagemin = require(`gulp-imagemin`);
var pngquant = require(`imagemin-pngquant`);
var spritesmith = require(`gulp.spritesmith`);

//錯誤捕獲
var plumber = require(`gulp-plumber`);

// 設定相關路徑
var paths = {
    wxml: `html`,
    wxss: `styles`,
    js: `scripts`,
    img: `images`
};

gulp.task(`wxml`, function() {
    var src = [paths.wxml + `/**/*.html`];
    return gulp.src(src)
        .pipe(plumber({
            errorHandler: handleError
        }))
        .pipe(foreach(function(stream, file) {
            return stream.pipe(rename(file.relative.replace(/.html/gi, `.wxml`)));
        }))
        .pipe(gulp.dest(`../`))
        .pipe(notify({
            onLast: true,
            message: "transform wxml success!"
        }));
});

gulp.task(`wxjs`, function() {
    var src = [paths.js + `/**/*.js`];
    return gulp.src(src)
        .pipe(plumber({
            errorHandler: handleError
        }))
        .pipe(gulp.dest(`../`))
        .pipe(notify({
            onLast: true,
            message: "transform wxjs success!"
        }))
});

gulp.task(`wxss`, function() {
    var src = [paths.wxss + `/**/*!(_).scss`];
    return gulp.src(src)
        .pipe(plumber({
            errorHandler: handleError
        }))
        .pipe(foreach(function(stream, file) {
            return stream
                .pipe(path.extname(file.relative) == `.less` ? less() : sass().on(`error`, sass.logError));
        }))
        .pipe(csscomb())
        .pipe(minifycss({
            aggressiveMerging: false,
            advanced: false,
            compatibility: `ie7`,
            keepBreaks: true
        }))
        .pipe(cssbeautify({
            autosemicolon: true
        }))
        .pipe(foreach(function(stream, file) {
            return stream.pipe(rename(file.relative.replace(/.css/gi, `.wxss`)));
        }))
        .pipe(gulp.dest(`../`))
        .pipe(notify({
            onLast: true,
            message: "browser reload for css"
        }));
});

gulp.task(`watch`, function() { //監聽檔案改變觸發相應任務
    gulp.watch([paths.wxml + `/**/*.html`], [`wxml`]);
    gulp.watch([paths.js + `/**/*.js`], [`wxjs`]);
    gulp.watch([paths.wxss + `/**/*.scss`], [`wxss`]);
});

gulp.task(`default`, [`watch`]);

function handleError(err) {
    gutil.beep();
    gutil.log(err.toString());
    notify.onError("Error: <%= error.message="" %="">")(err);
    this.emit(`end`);
}複製程式碼

程式碼會有冗餘的部分沒有仔細刪除,忽略即可。使用時需要根據提示安裝必要的外掛

關於微信小程式,如果基礎不錯的同學,可以去積極嘗試一下的,感覺官方文件寫的很清晰,模組化經驗比較豐富的應該會很容易上手。對於基礎比較薄弱的同學保持關注也是非常必要的,抓緊時間掌握基礎才是關鍵啊。

因為小程式大家都處於學習階段,所以大家都在探索嘛,希望大家多多發文章,相互交流學習,一起進步^_^。最近我也會持續更新自己在學習中的收穫與一些實踐demo,歡迎關注我的公眾號,一起交流。

微信小程式之程式碼構建初探:如何繼續使用html與css開發小程式

相關文章