|
| 1 | +const fs = require("fs"); |
| 2 | +const path = require("path"); |
| 3 | +const { promisify } = require("util"); |
| 4 | +const loaderUtils = require("loader-utils"); |
| 5 | + |
| 6 | +const readDir = promisify(fs.readdir); |
| 7 | +const readFile = promisify(fs.readFile); |
| 8 | + |
| 9 | +module.exports = async function (source) { |
| 10 | + const done = this.async(); |
| 11 | + const filePath = this.context; |
| 12 | + const fileName = this.resourcePath.replace(filePath + "/", ""); |
| 13 | + |
| 14 | + const options = loaderUtils.getOptions(this) || {}; |
| 15 | + const styleRegExp = new RegExp(options.style.map(it => `${fileName}\\.${it}$`).join("|")); |
| 16 | + const scriptRegExp = new RegExp(options.script.map(it => `${fileName}\\.${it}$`).join("|")); |
| 17 | + |
| 18 | + let stylePath = null; |
| 19 | + let scriptPath = null; |
| 20 | + |
| 21 | + const files = await readDir(filePath); |
| 22 | + files.forEach(file => { |
| 23 | + if (styleRegExp.test(file)) stylePath = path.join(filePath, file); |
| 24 | + if (scriptRegExp.test(file)) scriptPath = path.join(filePath, file); |
| 25 | + }); |
| 26 | + |
| 27 | + // 存在匹配节点且原`.vue`文件不存在`script`标签 |
| 28 | + if (scriptPath && !/<script[\s\S]*?>/.test(source)) { |
| 29 | + const extName = scriptPath.split(".").pop(); |
| 30 | + if (extName) { |
| 31 | + const content = await readFile(scriptPath, "utf8"); |
| 32 | + const scriptTagContent = [ |
| 33 | + "<script ", |
| 34 | + extName === "js" ? "" : `lang="${extName}" `, |
| 35 | + ">\n", |
| 36 | + content, |
| 37 | + "</script>", |
| 38 | + ].join(""); |
| 39 | + source = source + "\n" + scriptTagContent; |
| 40 | + } |
| 41 | + } |
| 42 | + |
| 43 | + // 存在匹配节点且原`.vue`文件不存在`style`标签 |
| 44 | + if (stylePath && !/<style[\s\S]*?>/.test(source)) { |
| 45 | + const extName = stylePath.split(".").pop(); |
| 46 | + if (extName) { |
| 47 | + const content = await readFile(stylePath, "utf8"); |
| 48 | + const scoped = /\/\/[\s]scoped[\n]/.test(content) ? true : false; |
| 49 | + const styleTagContent = [ |
| 50 | + "<style ", |
| 51 | + extName === "css" ? "" : `lang="${extName}" `, |
| 52 | + scoped ? "scoped " : " ", |
| 53 | + ">\n", |
| 54 | + content, |
| 55 | + "</style>", |
| 56 | + ].join(""); |
| 57 | + source = source + "\n" + styleTagContent; |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + // console.log(stylePath, scriptPath, source); |
| 62 | + done(null, source); |
| 63 | +}; |
0 commit comments