美文网首页
vue项目源码-rollup-plugin-alias插件问题解

vue项目源码-rollup-plugin-alias插件问题解

作者: Yezzle | 来源:发表于2020-02-17 12:33 被阅读0次

    在我用windows系统运行vue项目dev分支时,报了以下错误:

    [!] (plugin Rollup Core) Error: Could not load F:\F盘\workspaces\vsCode2\vueProjects\vueSource\vue\src\core\config (imported by F:\F盘\workspaces\vsCode2\vueProjects\vueSource\vue\src\platforms\web\entry-runtime-with-compiler.js): ENOENT: no such file or directory, open 'F:\F盘\workspaces\vsCode2\vueProjects\vueSource\vue\src\core\config'

    定位:看文件夹下确实是有这个config.js的,于是我在源码entry-runtime-with-compiler.js中config后加上.js后重新运行,index又找不到了,网上搜索一下发现主要是rollup-plugin-alias这个插件windows不兼容的问题,也有人自己修改了插件并提交到了自己的git仓库,但是他这里需要自己再去安装依赖构建,对于只是一个函数的插件我觉得没有必要,所以我准备直接用rollup调用他的原函数。 于是经过一顿修改后直接开启调试:
    1. 修改rollup-plugin-alias/src/index.js,将其中的es6模块引入方式改为require,
    2. 修改package.json文件main属性为src/index.js, 以便直接从源码中调试:

       node --inspect-brk .\node_modules\rollup\bin\rollup -w -c scripts/config.js --sourcemap --environment TARGET:web-full-dev
    

    打开chrome并输入地址: chrome://inspect/ 打开调试窗口调试
    分析: 通过调试分析发现,这个alias插件只做了一件事,就是把所有引入的相对路径以绝对路径的方式返回给rollup,所以就可以在这里搞事情了:对于没有js后缀的手动给他加速后缀并返回路径即可

    下面是我修改之后的index.js:

    const fs = require('fs');
    const { platform } = require('os');
    const path = require('path');
    const posix = path.posix;
    const slash = require('slash');
    
    const VOLUME = /^([A-Z]:)/;
    const IS_WINDOWS = platform() === 'win32';
    
    // Helper functions
    const noop = () => null;
    const matches = (key, importee) => {
      if (importee.length < key.length) {
        return false;
      }
      if (importee === key) {
        return true;
      }
      const importeeStartsWithKey = (importee.indexOf(key) === 0);
      const importeeHasSlashAfterKey = (importee.substring(key.length)[0] === '/');
      return importeeStartsWithKey && importeeHasSlashAfterKey;
    };
    const endsWith = (needle, haystack) => haystack.slice(-needle.length) === needle;
    // const isFilePath = id => /^\.?\//.test(id);
    const isFilePath = id => /(^\.?\/)|(^[a-zA-Z]\:(\\|\/))/.test(id);
    const exists = (uri) => {
      try {
        return fs.statSync(uri).isFile();
      } catch (e) {
        return false;
      }
    };
    
    const resolvePath = (fpath, resolves) => {
      if(exists(fpath)) return path.resolve(fpath);
      return doResolves(fpath, resolves, 0)
    }
    
    const doResolves = (fpath, resolves, i) =>{
      let newPath = path.resolve(`${fpath}${resolves[i]}`);
      if(!resolves[i]) return path.resolve(fpath)
      if(exists(newPath)) return newPath;
      return doResolves(fpath, resolves, i+1)
    }
    
    const normalizeId = (id) => {
      if ((IS_WINDOWS && typeof id === 'string') || VOLUME.test(id)) {
        return slash(id.replace(VOLUME, ''));
      }
    
      return id;
    };
    
    module.exports = function alias(options = {}) {
      const hasResolve = Array.isArray(options.resolve);
      const resolve = hasResolve ? options.resolve : ['.js'];
      const aliasKeys = hasResolve
        ? Object.keys(options).filter(k => k !== 'resolve') : Object.keys(options);
    
      // No aliases?
      if (!aliasKeys.length) {
        return {
          resolveId: noop,
        };
      }
    
      return {
        resolveId(importee, importer) {
          const importeeId = normalizeId(importee);
          const importerId = normalizeId(importer);
    
          // First match is supposed to be the correct one
          const toReplace = aliasKeys.find(key => matches(key, importeeId));
    
          if (!toReplace || !importerId) {
            return null;
          }
    
          const entry = options[toReplace];
    
          let updatedId = normalizeId(importeeId.replace(toReplace, entry));
    
          if (isFilePath(updatedId)) {
            const directory = posix.dirname(importerId);
    
            // Resolve file names
            const filePath = posix.resolve(directory, updatedId);
            const match = resolve.map(ext => (endsWith(ext, filePath) ? filePath : `${filePath}${ext}`))
              .find(exists);
    
            if (match) {
              updatedId = match;
              // To keep the previous behaviour we simply return the file path
              // with extension
            } else if (endsWith('.js', filePath)) {
              updatedId = filePath;
            } else {
              updatedId = filePath + '.js';
            }
          }
    
          // if alias is windows absoulate path return resolved path or
          // rollup on windows will throw:
          //  [TypeError: Cannot read property 'specifier' of undefined]
          if (VOLUME.test(entry)) {
            // return path.resolve(updatedId);
            return resolvePath(updatedId, resolve)
          }
          return updatedId;
        },
      };
    }
    
    

    相关文章

      网友评论

          本文标题:vue项目源码-rollup-plugin-alias插件问题解

          本文链接:https://www.haomeiwen.com/subject/varbfhtx.html