UNPKG

lesslint

Version:
162 lines (135 loc) 15.3 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkString = checkString; exports.check = check; var _path = require('path'); var _fs = require('fs'); var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk); var _postcssLess = require('postcss-less'); var _postcssLess2 = _interopRequireDefault(_postcssLess); var _postcss = require('postcss'); var _postcss2 = _interopRequireDefault(_postcss); var _util = require('./util'); var _config = require('./config'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 'use strict'; /** * rule 逻辑实现的文件夹路径 */ /** * @file checker 针对 less 文件的校验器 * @author ielgnaw(wuji0223@gmail.com) */ var ruleDir = (0, _path.join)(__dirname, './rule'); /** * 检测 css 文件内容 * * @param {string} fileContent 文件内容 * @param {string} filePath 文件路径,根据这个参数来设置 less 编译时的 paths * @param {Object=} realConfig 检测规则的配置,可选 * * @return {Promise} Promise 对象 */ function checkString(fileContent, filePath, realConfig) { // 这里把文件内容的 \r\n 统一替换成 \n,便于之后获取行号 fileContent = fileContent.replace(/\r\n?/g, '\n'); // postcss 插件集合即规则检测的文件集合 var plugins = []; Object.getOwnPropertyNames(realConfig).forEach(function (prop) { var ruleFilePath = (0, _path.join)(ruleDir, prop) + '.js'; if ((0, _fs.existsSync)(ruleFilePath)) { plugins.push(require((0, _path.join)(ruleDir, prop)).check({ ruleVal: realConfig[prop], // 实际上在 postcss 的 plugin 里面通过 node.source.input.css 也可以拿到文件内容 // 但是通过这种方式拿到的内容是去掉 BOM 的,因此在检测 no-bom 规则时候会有问题 // 所以这里把文件的原内容传入进去 fileContent: fileContent, filePath: filePath })); } }); // 不合法的信息集合 var invalidList = []; var invalid = { path: '', messages: [] }; var checkPromise = new Promise(function (resolve, reject) { (0, _postcss2.default)(plugins).process(fileContent, { syntax: _postcssLess2.default }).then(function (result) { result.warnings().forEach(function (data) { invalid.messages.push({ ruleName: data.ruleName, line: data.line, col: data.col, errorChar: data.errorChar || '', message: data.message, colorMessage: data.colorMessage }); if (invalid.path !== filePath) { invalid.path = filePath; invalidList.push(invalid); } }); resolve(invalidList); // const parserRet = safeStringify(result.root.toResult().root, null, 4); // const outputFile = join(__dirname, '../ast.json'); // writeFileSync(outputFile, parserRet); }).catch(function (e) { // 这里 catch 的是代码中的错误 var str = e.toString(); invalid.messages.push({ ruleName: 'CssSyntaxError', line: e.line, col: e.column, message: str, colorMessage: _chalk2.default.red(str) }); if (invalid.path !== filePath) { invalid.path = filePath; invalidList.push(invalid); } reject(invalidList); }); }); return checkPromise; } /** * 校验文件 * * @param {Object} file 包含 path 和 content 键的对象 * @param {Array} errors 本分类的错误信息数组 * @param {Function} done 校验完成的通知回调 * * @return {Function} checkString 方法 */ function check(file, errors, done) { if ((0, _util.isIgnored)(file.path, '.lesslintignore')) { done(); return; } /** * checkString 的 promise 的 reject 和 resolve 的返回值的结构以及处理方式都是一样的 * reject 指的是 parse 本身的错误以及 ast.toCSS({}) 的错误,这些代表程序的错误。 * resolve 代表的是 lesslint 检测出来的问题 * * @param {Array.<Object>} invalidList 错误信息集合 */ var callback = function callback(invalidList) { if (invalidList.length) { invalidList.forEach(function (invalid) { errors.push({ path: invalid.path, messages: invalid.messages }); }); } done(); }; return checkString(file.content, file.path, (0, _config.loadConfig)(file.path, true)).then(callback).catch(callback); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jaGVja2VyLmpzIl0sIm5hbWVzIjpbImNoZWNrU3RyaW5nIiwiY2hlY2siLCJydWxlRGlyIiwiX19kaXJuYW1lIiwiZmlsZUNvbnRlbnQiLCJmaWxlUGF0aCIsInJlYWxDb25maWciLCJyZXBsYWNlIiwicGx1Z2lucyIsIk9iamVjdCIsImdldE93blByb3BlcnR5TmFtZXMiLCJmb3JFYWNoIiwicHJvcCIsInJ1bGVGaWxlUGF0aCIsInB1c2giLCJyZXF1aXJlIiwicnVsZVZhbCIsImludmFsaWRMaXN0IiwiaW52YWxpZCIsInBhdGgiLCJtZXNzYWdlcyIsImNoZWNrUHJvbWlzZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicHJvY2VzcyIsInN5bnRheCIsInBvc3Rjc3NMZXNzIiwidGhlbiIsInJlc3VsdCIsIndhcm5pbmdzIiwicnVsZU5hbWUiLCJkYXRhIiwibGluZSIsImNvbCIsImVycm9yQ2hhciIsIm1lc3NhZ2UiLCJjb2xvck1lc3NhZ2UiLCJjYXRjaCIsInN0ciIsImUiLCJ0b1N0cmluZyIsImNvbHVtbiIsImNoYWxrIiwicmVkIiwiZmlsZSIsImVycm9ycyIsImRvbmUiLCJjYWxsYmFjayIsImxlbmd0aCIsImNvbnRlbnQiXSwibWFwcGluZ3MiOiI7Ozs7O1FBOEJnQkEsVyxHQUFBQSxXO1FBeUZBQyxLLEdBQUFBLEs7O0FBbEhoQjs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFFQTs7QUFDQTs7OztBQUVBOztBQUVBOzs7QUFoQkE7Ozs7O0FBbUJBLElBQU1DLFVBQVUsZ0JBQUtDLFNBQUwsRUFBZ0IsUUFBaEIsQ0FBaEI7O0FBRUE7Ozs7Ozs7OztBQVNPLFNBQVNILFdBQVQsQ0FBcUJJLFdBQXJCLEVBQWtDQyxRQUFsQyxFQUE0Q0MsVUFBNUMsRUFBd0Q7QUFDM0Q7QUFDQUYsa0JBQWNBLFlBQVlHLE9BQVosQ0FBb0IsUUFBcEIsRUFBOEIsSUFBOUIsQ0FBZDs7QUFFQTtBQUNBLFFBQU1DLFVBQVUsRUFB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L0MsWUFBWTZDLEtBQUtLLE9BQWpCLEVBQTBCTCxLQUFLMUIsSUFBL0IsRUFBcUMsd0JBQVcwQixLQUFLMUIsSUFBaEIsRUFBc0IsSUFBdEIsQ0FBckMsRUFBa0VTLElBQWxFLENBQXVFb0IsUUFBdkUsRUFBaUZWLEtBQWpGLENBQXVGVSxRQUF2RixDQUFQO0FBQ0giLCJmaWxlIjoiY2hlY2tlci5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGUgY2hlY2tlciDpkojlr7kgbGVzcyDmlofku7bnmoTmoKHpqozlmahcbiAqIEBhdXRob3IgaWVsZ25hdyh3dWppMDIyM0BnbWFpbC5jb20pXG4gKi9cblxuaW1wb3J0IHtqb2lufSBmcm9tICdwYXRoJztcbmltcG9ydCB7ZXhpc3RzU3luY30gZnJvbSAnZnMnO1xuaW1wb3J0IGNoYWxrIGZyb20gJ2NoYWxrJztcbmltcG9ydCBwb3N0Y3NzTGVzcyBmcm9tICdwb3N0Y3NzLWxlc3MnO1xuaW1wb3J0IHBvc3Rjc3MgZnJvbSAncG9zdGNzcyc7XG5cbmltcG9ydCB7aXNJZ25vcmVkfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IHtsb2FkQ29uZmlnfSBmcm9tICcuL2NvbmZpZyc7XG5cbid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBydWxlIOmAu+i+keWunueOsOeahOaWh+S7tuWkuei3r+W+hFxuICovXG5jb25zdCBydWxlRGlyID0gam9pbihfX2Rpcm5hbWUsICcuL3J1bGUnKTtcblxuLyoqXG4gKiDmo4DmtYsgY3NzIOaWh+S7tuWGheWuuVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlQ29udGVudCDmlofku7blhoXlrrlcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCDmlofku7bot6/lvoTvvIzmoLnmja7ov5nkuKrlj4LmlbDmnaXorr7nva4gbGVzcyDnvJbor5Hml7bnmoQgcGF0aHNcbiAqIEBwYXJhbSB7T2JqZWN0PX0gcmVhbENvbmZpZyDmo4DmtYvop4TliJnnmoTphY3nva7vvIzlj6/pgIlcbiAqXG4gKiBAcmV0dXJuIHtQcm9taXNlfSBQcm9taXNlIOWvueixoVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tTdHJpbmcoZmlsZUNvbnRlbnQsIGZpbGVQYXRoLCByZWFsQ29uZmlnKSB7XG4gICAgLy8g6L+Z6YeM5oqK5paH5Lu25YaF5a6555qEIFxcclxcbiDnu5/kuIDmm7/mjaLmiJAgXFxu77yM5L6/5LqO5LmL5ZCO6I635Y+W6KGM5Y+3XG4gICAgZmlsZUNvbnRlbnQgPSBmaWxlQ29udGVudC5yZXBsYWNlKC9cXHJcXG4/L2csICdcXG4nKTtcblxuICAgIC8vIHBvc3Rjc3Mg5o+S5Lu26ZuG5ZCI5Y2z6KeE5YiZ5qOA5rWL55qE5paH5Lu26ZuG5ZCIXG4gICAgY29uc3QgcGx1Z2lucyA9IFtdO1xuXG4gICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoXG4gICAgICAgIHJlYWxDb25maWdcbiAgICApLmZvckVhY2goXG4gICAgICAgIGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgICAgICAgICBjb25zdCBydWxlRmlsZVBhdGggPSBqb2luKHJ1bGVEaXIsIHByb3ApICsgJy5qcyc7XG4gICAgICAgICAgICBpZiAoZXhpc3RzU3luYyhydWxlRmlsZVBhdGgpKSB7XG4gICAgICAgICAgICAgICAgcGx1Z2lucy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICByZXF1aXJlKGpvaW4ocnVsZURpciwgcHJvcCkpLmNoZWNrKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVWYWw6IHJlYWxDb25maWdbcHJvcF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDlrp7pmYXkuIrlnKggcG9zdGNzcyDnmoQgcGx1Z2luIOmHjOmdoumAmui/hyBub2RlLnNvdXJjZS5pbnB1dC5jc3Mg5Lmf5Y+v5Lul5ou/5Yiw5paH5Lu25YaF5a65XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDkvYbmmK/pgJrov4fov5nnp43mlrnlvI/mi7/liLDnmoTlhoXlrrnmmK/ljrvmjokgQk9NIOeahO+8jOWboOatpOWcqOajgOa1iyBuby1ib20g6KeE5YiZ5pe25YCZ5Lya5pyJ6Zeu6aKYXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDmiYDku6Xov5nph4zmiormlofku7bnmoTljp/lhoXlrrnkvKDlhaXov5vljrtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVDb250ZW50OiBmaWxlQ29udGVudCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVQYXRoOiBmaWxlUGF0aFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICApO1xuXG4gICAgLy8g5LiN5ZCI5rOV55qE5L+h5oGv6ZuG5ZCIXG4gICAgY29uc3QgaW52YWxpZExpc3QgPSBbXTtcblxuICAgIGNvbnN0IGludmFsaWQgPSB7XG4gICAgICAgIHBhdGg6ICcnLFxuICAgICAgICBtZXNzYWdlczogW11cbiAgICB9O1xuXG4gICAgY29uc3QgY2hlY2tQcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBwb3N0Y3NzKHBsdWdpbnMpLnByb2Nlc3MoZmlsZUNvbnRlbnQsIHtcbiAgICAgICAgICAgIHN5bnRheDogcG9zdGNzc0xlc3NcbiAgICAgICAgfSkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgICAgcmVzdWx0Lndhcm5pbmdzKCkuZm9yRWFjaChkYXRhID0+IHtcbiAgICAgICAgICAgICAgICBpbnZhbGlkLm1lc3NhZ2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBydWxlTmFtZTogZGF0YS5ydWxlTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbGluZTogZGF0YS5saW5lLFxuICAgICAgICAgICAgICAgICAgICBjb2w6IGRhdGEuY29sLFxuICAgICAgICAgICAgICAgICAgICBlcnJvckNoYXI6IGRhdGEuZXJyb3JDaGFyIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBkYXRhLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yTWVzc2FnZTogZGF0YS5jb2xvck1lc3NhZ2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoaW52YWxpZC5wYXRoICE9PSBmaWxlUGF0aCkge1xuICAgICAgICAgICAgICAgICAgICBpbnZhbGlkLnBhdGggPSBmaWxlUGF0aDtcbiAgICAgICAgICAgICAgICAgICAgaW52YWxpZExpc3QucHVzaChpbnZhbGlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlc29sdmUoaW52YWxpZExpc3QpO1xuXG4gICAgICAgICAgICAvLyBjb25zdCBwYXJzZXJSZXQgPSBzYWZlU3RyaW5naWZ5KHJlc3VsdC5yb290LnRvUmVzdWx0KCkucm9vdCwgbnVsbCwgNCk7XG4gICAgICAgICAgICAvLyBjb25zdCBvdXRwdXRGaWxlID0gam9pbihfX2Rpcm5hbWUsICcuLi9hc3QuanNvbicpO1xuICAgICAgICAgICAgLy8gd3JpdGVGaWxlU3luYyhvdXRwdXRGaWxlLCBwYXJzZXJSZXQpO1xuICAgICAgICB9KS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgIC8vIOi/memHjCBjYXRjaCDnmoTmmK/ku6PnoIHkuK3nmoTplJnor69cbiAgICAgICAgICAgIGNvbnN0IHN0ciA9IGUudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIGludmFsaWQubWVzc2FnZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgcnVsZU5hbWU6ICdDc3NTeW50YXhFcnJvcicsXG4gICAgICAgICAgICAgICAgbGluZTogZS5saW5lLFxuICAgICAgICAgICAgICAgIGNvbDogZS5jb2x1bW4sXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogc3RyLFxuICAgICAgICAgICAgICAgIGNvbG9yTWVzc2FnZTogY2hhbGsucmVkKHN0cilcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoaW52YWxpZC5wYXRoICE9PSBmaWxlUGF0aCkge1xuICAgICAgICAgICAgICAgIGludmFsaWQucGF0aCA9IGZpbGVQYXRoO1xuICAgICAgICAgICAgICAgIGludmFsaWRMaXN0LnB1c2goaW52YWxpZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWplY3QoaW52YWxpZExpc3QpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBjaGVja1Byb21pc2U7XG59XG5cbi8qKlxuICog5qCh6aqM5paH5Lu2XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGZpbGUg5YyF5ZCrIHBhdGgg5ZKMIGNvbnRlbnQg6ZSu55qE5a+56LGhXG4gKiBAcGFyYW0ge0FycmF5fSBlcnJvcnMg5pys5YiG57G755qE6ZSZ6K+v5L+h5oGv5pWw57uEXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lIOagoemqjOWujOaIkOeahOmAmuefpeWbnuiwg1xuICpcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBjaGVja1N0cmluZyDmlrnms5VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrKGZpbGUsIGVycm9ycywgZG9uZSkge1xuICAgIGlmIChpc0lnbm9yZWQoZmlsZS5wYXRoLCAnLmxlc3NsaW50aWdub3JlJykpIHtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogY2hlY2tTdHJpbmcg55qEIHByb21pc2Ug55qEIHJlamVjdCDlkowgcmVzb2x2ZSDnmoTov5Tlm57lgLznmoTnu5PmnoTku6Xlj4rlpITnkIbmlrnlvI/pg73mmK/kuIDmoLfnmoRcbiAgICAgKiByZWplY3Qg5oyH55qE5pivIHBhcnNlIOacrOi6q+eahOmUmeivr+S7peWPiiBhc3QudG9DU1Moe30pIOeahOmUmeivr++8jOi/meS6m+S7o+ihqOeoi+W6j+eahOmUmeivr+OAglxuICAgICAqIHJlc29sdmUg5Luj6KGo55qE5pivIGxlc3NsaW50IOajgOa1i+WHuuadpeeahOmXrumimFxuICAgICAqXG4gICAgICogQHBhcmFtIHtBcnJheS48T2JqZWN0Pn0gaW52YWxpZExpc3Qg6ZSZ6K+v5L+h5oGv6ZuG5ZCIXG4gICAgICovXG4gICAgY29uc3QgY2FsbGJhY2sgPSBpbnZhbGlkTGlzdCA9PiB7XG4gICAgICAgIGlmIChpbnZhbGlkTGlzdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGludmFsaWRMaXN0LmZvckVhY2goaW52YWxpZCA9PiB7XG4gICAgICAgICAgICAgICAgZXJyb3JzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiBpbnZhbGlkLnBhdGgsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VzOiBpbnZhbGlkLm1lc3NhZ2VzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBkb25lKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBjaGVja1N0cmluZyhmaWxlLmNvbnRlbnQsIGZpbGUucGF0aCwgbG9hZENvbmZpZyhmaWxlLnBhdGgsIHRydWUpKS50aGVuKGNhbGxiYWNrKS5jYXRjaChjYWxsYmFjayk7XG59XG4iXX0=