Heim  >  Artikel  >  WeChat-Applet  >  Design und Implementierung des WeChat-Applet-Konverter-Loaders

Design und Implementierung des WeChat-Applet-Konverter-Loaders

coldplay.xixi
coldplay.xixinach vorne
2020-11-19 17:36:123826Durchsuche

Mini-Tutorial zur Programmentwicklung Die Kolumne stellt das Design und die Implementierung des Loaders vor.

Design und Implementierung des WeChat-Applet-Konverter-Loaders

Die Loader-Konfiguration in der Konfigurationsdatei

kann den Regeln gemäß der Konfigurationsdatei entsprechen, um den entsprechenden Loader auszuführen.

// analyze.config.js
// 引入loader
const jsLoader = require('./lib/jsLoader')
const jsonLoader = require('./lib/jsonLoader')
const cssLoader = require('./lib/cssLoader')
const htmlLoader = require('./lib/htmlLoader')
const signLoader = require('./lib/signLoader')
const config = {
    entry: './',
    output: {
        name: 'dist',
        src: './'
    },
    module: [
        {
            test: /\.js$/,
            loader: [signLoader, jsLoader],
        },
        {
            test: /\.wxss$/,
            loader: [cssLoader],
            outputPath: (outputPath) => outputPath.replace('.wxss', '.acss')
        },
        {
            test: /\.wxml$/,
            loader: [htmlLoader],
            outputPath: (outputPath) => outputPath.replace('.wxml', '.axml')
        },
        {
            test: /\.json$/,
            loader: [jsonLoader],
        },
    ]
}
module.exports = config

Spezifische Loader-Implementierung
Nehmen Sie jsLoader als Beispiel, empfangen Sie den Quellcode als Parameter und geben Sie den nach der Kompilierung erhaltenen neuen Quellcode zurück

// 前几篇中封装的js转换器
const JsParser = require('./JsParser')
function loader(source) {
    
    const jsParser = new JsParser()
    let ast = jsParser.parse(source)
    ast = jsParser.astConverter(ast)
    return jsParser.astToCode(ast)
}
module.exports = loader

Unterschiedliche Dateiauswahlen entsprechen dem Loader

// 重写Analyze函数中的analyzeFileToLoard文件分析部分
function Analyze(filePath, outputPath){
    if (fs.statSync(filePath).isDirectory()) {
        const files = fs.readdirSync(filePath)
        files.forEach(file => {
            const currentFilePath = filePath+'/'+file
            const currentOutputPath = outputPath+'/'+file
            if(fs.statSync(currentFilePath).isDirectory()) {
                fs.mkdirSync(currentOutputPath)
                Analyze(currentFilePath, currentOutputPath)
            } else analyzeFileToLoard(currentFilePath, currentOutputPath)
        })
    } else analyzeFileToLoard(filePath, outputPath)
}
function analyzeFileToLoard(inputPath, outputPath) {
    let source = readFile(inputPath) // 读取源码
    const loaders = config.module
    loaders.forEach(loader => { // 遍历配置文件,看是否有匹配文件的loader规则
        if (loader.test.test(inputPath)) {
            // 使用loader
            source = useLoader(source, loader.loader, outputPath)
            // 输出路径处理函数
            if (loader.outputPath) outputPath = loader.outputPath(outputPath)
        }
    })
    writeFile(outputAppPath(outputPath), source) // 将处理过后的源码写入文件
}

Loader Filterung und Ausführung

Die Ausführung des Laders erfolgt in umgekehrter Reihenfolge, von rechts nach links. Hier verwenden wir zunächst den synchronen Lader zur Diskussion.
Es gibt eine Pitch-Phase, bevor der Loader ausgeführt wird. Ich denke, dass die Benennungsmethode Pitch nicht besonders geeignet ist. Ich nenne sie lieber die Filterphase. Führen Sie zunächst die Pitch-Methode nacheinander auf dem Loader aus. Wenn der Pitch einen Rückgabewert hat, wird der vor dem Loader ausgeführte Loader nicht mehr ausgeführt.

function useLoader(source, loaders = []) {
    // 执行loader存储列表
    const loaderList = []
    // 递归去筛选需要执行的loader
    function loaderFilter(loaders) {
        const [firstLoader, ...ortherLoader] = loaders
        if (loaders.length === 0) return
        // 执行pitch,并将剩余的loader传入作为参数
        if (firstLoader.pitch && firstLoader.pitch(ortherLoader)) return ortherLoader
        else {
            // 将可用loader加入待执行列表
            loaderList.push(firstLoader)
            // 剩余loader作为参数 递归调用
            loaderFilter(ortherLoader)
        }
    }
    // 大概,暂时用不到。。。
    const remainLoader = loaderFilter(loaders)
    // 同步loader逆序执行
    function runLoader(source, loaderList) {
        const loader = loaderList.pop()
        let newSource = loader(source)
        if (loaderList.length > 0) return runLoader(newSource, loaderList)
        else return newSource
    }
    source = runLoader(source, loaderList)
    return source
}

Experiment
Schreiben Sie einen signLoader, um zu sehen, ob der Loader in umgekehrter Reihenfolge ausgeführt werden kann, wie wir dachten

function loader(source) {
let sign = `/**
* @Author: LY
*/
`
    source = sign + source
    return source
}
module.exports = loader

Ergebnis:

Dieser einfache Loader-Teil ist abgeschlossen, aber durch das Schreiben auf diese Weise können nur einige synchrone Loader ausgeführt werden Lader können nicht warten, bis die Ausführung abgeschlossen ist, bevor sie schreiben.

Design und Implementierung des WeChat-Applet-Konverter-Loaders

Verwandte Lernempfehlungen: Mini-Tutorial zur Programmentwicklung

Das obige ist der detaillierte Inhalt vonDesign und Implementierung des WeChat-Applet-Konverter-Loaders. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen