Contexte
Dans vue
, vous pouvez utiliser process.env pour accéder aux propriétés du fichier de configuration et rechercher le fichier de configuration correspondant en fonction des différents environnements,
.env
.env.development
.env.production
复制代码
Toujours dans le framework cross-end d'applet, par exemple mpx
, plusieurs frameworks cross-end prennent également en charge la possibilité de compiler de manière conditionnelle dans la dimension de fichier. documentation de compilation multiplateforme mpx
Le document explique la compilation conditionnelle de la dimension du fichier . Par exemple, il existe un composant de carte d'entreprise map.mpx dans le projet WeChat->Alipay. En raison des grandes différences dans les normes des composants de carte natifs dans WeChat et Alipay, ils ne peut pas être traduit via le framework. Effectuer directement une sortie multiplateforme. À ce stade, vous pouvez créer un nouveau map.ali.mpx au même emplacement et utiliser les normes techniques d'Alipay pour le développement. Le système de compilation chargera le fichier correspondant module selon le mode actuellement compilé. Lorsque le mode est ali , map.ali.mpx sera chargé en premier, sinon map.mpx sera chargé.
Si dans le
web
projet , comment implémente-t-on la fonction de compilation conditionnelle de la dimension fichier ?
avoir besoin
Cet article implémente cette fonctionnalité avec webpack loader
un .
La structure du répertoire du projet est la suivante :
// index.js
import bridge from './mode/bridge.js'
// 目录
├── mode
│ ├── bridge.js
│ ├── bridge.dev.js
│ └── bridge.prod.js
├── index.js
复制代码
- S'il est dans l'environnement de développement (dev), importez le fichier bridge.dev.js dans le mode ;
- S'il est dans l'environnement de production (prod), importez le fichier bridge.prod.js dans le mode ;
- Dans d'autres environnements, importez le fichier bridge.js en mode ;
Ceci
polymorphism-loader
est actuellement publié et peut être installé à l'aide de
Programme
Combinez les étapes d'implémentation en texte, puis convertissez le texte en code.
- Obtenez le contenu du fichier et faites correspondre la syntaxe du fichier importé, telle que :
import xxx from xxx
; - Obtenez l'adresse du fichier importé correspondant à l'étape précédente et vérifiez si le dossier contient le fichier polymorphe ;
- Si c'est le cas, remplacez l'adresse du fichier importé, sinon ne la modifiez pas ;
Passez options.mode
en , comme suit :
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'polymorphism-loader',
options: {
mode: 'prod'
}
}]
}
]
复制代码
accomplir
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)
}
复制代码
Définissez une getResource
méthode , transmettez le source
contenu source et renvoyez le contenu source traité. loaderUtils.getOptions
La méthode obtient la configuration entrante, où vous pouvez obtenir les mode
données . La syntaxe du fichier importé est obtenue par correspondance régulière, puis l'adresse du fichier importé est filtrée utils.getContextData
. Le chemin absolu et le nom de fichier de l'adresse du fichier importé sont obtenus par utils.genFileList
la méthode , tous les fichiers du dossier sont obtenus par le méthode, puis le traitement polymorphe est mis en correspondance par la utils.getModeFileName
méthode Le nom du fichier, et correspond enfin si le fichier polymorphe existe dans le fichier, et le remplace s'il existe.
Voici le contenu 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
}
复制代码
Résumer
À l'heure actuelle, il loader
s'agit de la première version et il existe de nombreux défauts connus, tels que des import from
déclarations de correspondance uniquement, l'absence de prise en charge des fichiers de style, l'absence de possibilité de filtrer les fichiers et seul webpack4 a été testé. Ces problèmes seront mis à jour et itérés lentement dans l'avenir.