antecedentes
En vue
, puede usar process.env para acceder a las propiedades en el archivo de configuración y encontrar el archivo de configuración correspondiente según los diferentes entornos,
.env
.env.development
.env.production
复制代码
Además, en el marco cruzado de subprogramas, por ejemplo mpx
, múltiples marcos cruzados también admiten la capacidad de compilar condicionalmente en la dimensión del archivo. documentación de compilación multiplataforma mpx
El documento explica la compilación condicional de la dimensión del archivo . Por ejemplo, hay un componente de mapa de negocios map.mpx en el proyecto WeChat->Alipay. Debido a las grandes diferencias en los estándares de los componentes de mapas nativos en WeChat y Alipay, no se puede traducir a través del marco. Realice directamente la salida multiplataforma. En este momento, puede crear un nuevo map.ali.mpx en la misma ubicación y usar los estándares técnicos de Alipay para el desarrollo en él. El sistema de compilación cargará el correspondiente módulo de acuerdo con el modo compilado actualmente. Cuando el modo es ali , map.ali.mpx se cargará primero, de lo contrario se cargará map.mpx.
Si en el
web
proyecto , ¿cómo implementamos la función de compilación condicional de la dimensión del archivo ?
necesidad
Este documento implementa esta capacidad con webpack loader
un .
La estructura del directorio del proyecto es la siguiente:
// index.js
import bridge from './mode/bridge.js'
// 目录
├── mode
│ ├── bridge.js
│ ├── bridge.dev.js
│ └── bridge.prod.js
├── index.js
复制代码
- Si está en el entorno de desarrollo (dev), importe el archivo bridge.dev.js en el modo;
- Si está en el entorno de producción (prod), importe el archivo bridge.prod.js en el modo;
- En otros entornos, importe el archivo bridge.js en modo;
Esto
polymorphism-loader
se lanzó actualmente y se puede instalar usando
Programa
Combina los pasos de implementación en texto y luego convierte el texto en código.
- Obtenga el contenido del archivo y haga coincidir la sintaxis del archivo importado, como:
import xxx from xxx
; - Obtenga la dirección del archivo importado que coincidió con el paso anterior y analice si la carpeta contiene el archivo polimórfico;
- Si la hay, reemplace la dirección del archivo importado, si no, no la modifique;
Pase options.mode
como , de la siguiente manera:
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'polymorphism-loader',
options: {
mode: 'prod'
}
}]
}
]
复制代码
realizar
const loaderUtils = require('loader-utils')
const utils = require('./utils')
/**
* 返回处理后的文件源
* @param {*} source 文件源
* @returns {string} 处理后的文件源
*/
function getResource (source) {
const options = loaderUtils.getOptions(this) || {}
let resource = source
let requireFileStatements = source.match(utils.REG.matchRequireStatements)
if (requireFileStatements && options.mode) {
for (let i = 0, len = requireFileStatements.length; i < len; i++) {
let requireFilePath = requireFileStatements[i].match(utils.REG.matchRequireFilePath)[0]
requireFilePath = requireFilePath.substring(1, requireFilePath.length - 1)
const { fileName, filePath } = utils.getContextData(this.context, requireFilePath)
const fileList = utils.genFileList(filePath)
const modeFileName = utils.getModeFileName(fileName, options.mode)
if (fileList.some(item => item.indexOf(modeFileName) > -1)) {
let list = requireFilePath.split('/')
list.pop()
list.push(modeFileName)
resource = resource.replace(requireFilePath, list.join('/'))
console.log(resource)
}
}
}
return resource
}
module.exports = function(
source,
map,
meta,
) {
const resource = getResource.apply(this, [source])
this.callback(null, resource, map, meta)
}
复制代码
Defina un getResource
método , pase el source
contenido de origen y devuelva el contenido de origen procesado. loaderUtils.getOptions
El método obtiene la configuración entrante, donde puede obtener los mode
datos . La sintaxis del archivo importado se obtiene mediante coincidencia regular y luego la dirección del archivo importado se utils.getContextData
filtra.La ruta absoluta y el nombre de archivo de la dirección del archivo importado se obtienen por utils.genFileList
el método, todos los archivos en la carpeta se obtienen por el método, y luego el procesamiento polimórfico se compara utils.getModeFileName
con el método.El nombre del archivo, y finalmente coincide si el archivo polimórfico existe en el archivo, y lo reemplaza si existe.
El siguiente es el contenido de utils.js
// utils.js
const fs = require("fs")
const REG = {
replaceFileName: /([^\\/]+)\.([^\\/]+)/i,
matchRequireStatements: /import.*from.*(\'|\")/g,
matchRequireFilePath: /(\"|\').*(\"|\')/g
}
/**
* 返回引入文件的绝对路径 和 文件名
* @param {string} context 当前加载的文件所在的文件夹路径 /polymorphism-loader/src
* @param {string} requireFilePath 文件中引入的路径 ./event/event
* @return {object}
* filePath: /polymorphism-loader/src/event
* fileName: event
*/
function getContextData (context, requireFilePath) {
function running (contextList, requireFilePathList) {
if (requireFilePathList.length) {
const name = requireFilePathList.shift()
switch (name) {
case '.':
return running(contextList, requireFilePathList)
case '..':
return running([contextList, contextList.pop()][0], requireFilePathList)
default:
return running([contextList, contextList.push(name)][0], requireFilePathList)
}
}
return contextList.join('/')
}
let requireFilePathList = requireFilePath.split('/')
let contextList = context.split('/')
let fileName = requireFilePathList.pop()
let filePath = running(contextList, requireFilePathList)
return {
fileName: fileName,
filePath: filePath
}
}
/**
* 获取文件夹下所有文件名
* @param {*} filePath 文件夹路径
* @returns {array}
*/
function genFileList (filePath) {
let filesList = []
let files = fs.readdirSync(filePath); // 需要用到同步读取
files.forEach((file) => {
let states = fs.statSync(filePath + '/' + file)
// 判断是否是目录,是就继续递归
if (states.isDirectory()) {
genFileList(filePath + '/' + file, filesList)
} else {
// 不是就将文件push进数组,此处可以正则匹配是否是 .js 先忽略
filesList.push(file)
}
})
return filesList
}
/**
* 返回组合多态文件名
* name.js ===> name.[mode].js
* @param {*} fileName
* @param {*} mode
* @returns {string}
*/
function getModeFileName (fileName, mode) {
let modeFileName = null
if (fileName.match(REG.replaceFileName)) {
fileName.replace(REG.replaceFileName, ($1, $2, $3) => {
modeFileName = $2 + '.' + mode + '.' + $3
})
} else {
modeFileName = fileName + '.' + mode
}
return modeFileName
}
module.exports = {
REG,
getContextData,
genFileList,
getModeFileName
}
复制代码
Resumir
En la actualidad, esta loader
es la primera versión y hay muchos defectos conocidos, como solo import from
sentencias coincidentes, no hay soporte para archivos de estilo, no hay capacidad para filtrar archivos y solo se ha probado webpack4. Estos problemas se actualizarán e iterarán lentamente en el futuro.