inject-main-css-to-independent-plugin.js 6.7 KB
Newer Older
1 2 3 4 5 6 7
const fs = require('fs-extra');
const path = require('path');
const { generateAsset } = require('./utils');
const {
    getIndependentPkgRoots,
    getIndependentEntryPages
} = require('@dcloudio/uni-mp-weixin/lib/independent-plugins/optimize-components-position/util');
8 9
const { wxComponentsStr } = require('./optimize-components-position/constant');
const weuiMiniprogramDir = 'weui-mp';
10 11 12 13 14

function generateCssSource (pkgMainCssPath, pkgLibraryCssPath, wxssSourceInfo) {
    const platforms = ['mp-weixin', 'mp-qq', 'mp-toutiao'];
    const presetStyle = platforms.includes(process.env.UNI_PLATFORM) ? '[data-custom-hidden="true"],[bind-data-custom-hidden="true"]{display: none !important;}' : '';

15 16 17
    const mainCssImport = pkgMainCssPath ? `@import '/${pkgMainCssPath}';` : '';
    const libraryCssImport = pkgLibraryCssPath ? `@import '/${pkgLibraryCssPath}';` : '';
    return `${mainCssImport}${libraryCssImport}
18 19 20 21 22
    ${wxssSourceInfo.source()}
    ${presetStyle}`;
}

function copyWeuiCssToIndependent (independentRoot) {
23
    const weuiCssRelativePath = `wxcomponents/${weuiMiniprogramDir}/weui-wxss/dist/style/weui.wxss`;
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
    const fromPath = path.resolve(process.env.UNI_INPUT_DIR, weuiCssRelativePath);
    const toPath = path.resolve(process.env.UNI_OUTPUT_DIR, `${independentRoot}/${weuiCssRelativePath}`);
    if (fs.existsSync(fromPath)) {
        fs.copySync(fromPath, toPath);
        return true;
    } else {
        console.warn('添加weui组件库到wxcomponents目录下');
    }
    return false;
}

function tryInsertWeuiCss (independentRoot, originalWxssStr) {
    const manifestConfig = process.UNI_MANIFEST;
    const weixinConfig = manifestConfig['mp-weixin'] || {};
    const independentSwitch = !!weixinConfig.independentSwitch;
    // 如果使用了weui,则需要注入weui样式
    const useExtendedWeUi = !!(weixinConfig.useExtendedLib || {}).weui;

    // 复制
    const successOrNot = copyWeuiCssToIndependent(independentRoot);

45
    const insertStr = `@import '/${independentRoot}/wxcomponents/${weuiMiniprogramDir}/weui-wxss/dist/style/weui.wxss'`;
46 47 48 49 50 51 52 53 54 55 56 57 58 59
    return (successOrNot && useExtendedWeUi) ? `${insertStr};${originalWxssStr}` : originalWxssStr;
}

// 独立分包页面不受app.wxss影响
// 独立分包中所有的页面需要导入main.wxss
class InjectMainCssToIndependentCssPlugin {
    apply (compiler) {
        compiler.hooks.emit.tapPromise('InjectMainCssToIndependentCssPlugin', compilation => {
            return new Promise((resolve, reject) => {
                try {
                    const thisCompilationAssets = compilation.assets;

                    const indendentRoots = getIndependentPkgRoots();
                    indendentRoots.forEach(indendentRoot => {
60 61 62 63 64 65 66 67 68 69 70
                        
                        let pkgMainCssPath = `${indendentRoot}/common/main.wxss`;
                        let pkgLibraryCssPath = `${indendentRoot}/common/library.wxss`;

                        if(!thisCompilationAssets[pkgMainCssPath]){
                            pkgMainCssPath = '';
                        }

                        if(!thisCompilationAssets[pkgLibraryCssPath]){
                            pkgLibraryCssPath = '';
                        }
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

                        const pkgPagesPath = getIndependentEntryPages(indendentRoot);
                        // const cacheSet = new Set();
                        // 获取所有页面和组件
                        // findAllPagesAndComponentsByIndependentRoot(thisCompilationAssets, indendentRoot, pkgPagesPath, cacheSet);
                        // const allPagesAndCompoents = [...cacheSet];

                        // 关键,app.wxss和页面.wxss 对组件的影响是一样的。只需要注入到页面即可
                        // 记:Component构造页面的化,不需要注入app.wxss。uniapp不存在该情况即页面均是通过Page构造,因此向页面注入
                        // https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html#%E7%BB%84%E4%BB%B6%E6%A0%B7%E5%BC%8F%E9%9A%94%E7%A6%BB
                        pkgPagesPath.forEach(pageAndComponentPath => {
                            if (pageAndComponentPath.startsWith('/')) {
                                pageAndComponentPath = pageAndComponentPath.substring(1);
                            }

86
                            if (pageAndComponentPath.indexOf(wxComponentsStr) >= 0) {
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
                                return;
                            }
                            const pageWxssPath = `${pageAndComponentPath}.wxss`;
                            const wxssSourceInfo = thisCompilationAssets[pageWxssPath];
                            if (!wxssSourceInfo) { // 有可能确实没有产出.wxss文件
                                console.log('invalid wxssSourceInfo', pageAndComponentPath);
                                return;
                            }

                            let wxssSource = generateCssSource(pkgMainCssPath, pkgLibraryCssPath, wxssSourceInfo);
                            wxssSource = tryInsertWeuiCss(indendentRoot, wxssSource);
                            thisCompilationAssets[pageWxssPath] = generateAsset(wxssSource);
                        });
                    });

                    resolve();
                } catch (e) {
                    console.error('independent.error', 'InjectMainCssToIndependentCssPlugin', e);
                    reject(e);
                }
            });
        });
    }
}

module.exports = InjectMainCssToIndependentCssPlugin;


//
// function findAllPagesAndComponentsByIndependentRoot (thisCompilationAssets, independentRoot, pageOrComponents = [], cacheSet = new Set()) {
//     pageOrComponents.forEach(pageOrComponentPath => {
//         // 防止递归
//         const recured = cacheSet.has(pageOrComponentPath);
//         if (recured) return;
//         cacheSet.add(pageOrComponentPath);
//
//         pageOrComponentPath = getNewComponentPathInIndependentPkg(independentRoot, pageOrComponentPath);
//         if (pageOrComponentPath.startsWith('/')) {
//             pageOrComponentPath = pageOrComponentPath.substring(1);
//         }
//         const pathWithSuffix = `${pageOrComponentPath}.json`;
//         const assetInfo = thisCompilationAssets[pathWithSuffix]; // 原生组件的json文件在copy时保存到了 compilationAssets
//         const jsonObj = assetInfo && JSON.parse(assetInfo.source().toString());
//
//         if (!jsonObj) {
//             console.error('independent.error.recurIndependentJson', pageOrComponentPath);
//             return;
//         }
//
//         const usingComponents = Object.values(jsonObj.usingComponents || {});
//         findAllPagesAndComponentsByIndependentRoot(thisCompilationAssets, independentRoot, usingComponents, cacheSet);
//     });
// }