2017-03-09 190 views
0

我在创建指令npm包时遇到问题。错误:无法解析指令的所有参数

我已经为@Component创建了包,但是这是我为@Directive创建的第一个包。

我面临的问题是,当我运行ng serve构建完成确定,但是当我加载页面时,我得到Error: Can't resolve all parameters for HighlightDirective

好奇的是,如果运行ng serve --aot问题没有出现。

所以,该软件包只能与--AOT一起使用,并且会在JIT中抛出错误。

可能是--AOT在解析我的自定义指令之前包含了一些必需的包。在JIT中不会发生尝试在另一个模块加载所需包之前加载该指令的情况。

我做了一个调度器来显示问题,我将离开包的URL,以便您可以看到我的代码。

textarea的-resize.directive.ts

import { Directive, ElementRef, Input } from '@angular/core'; 

@Directive({ selector: 'textarea[textarea-resize]' }) 
export class HighlightDirective { 
    constructor(el: ElementRef) { 
     el.nativeElement.style.backgroundColor = 'yellow'; 
    } 
} 

诗篇。指令名现在是HighlightDirective,即使是文件名textarea-resize.directive,因为我已经用angular.io文档替换了我的指令,以确保指令sintax是正确的。

我也测试过直接从我的应用程序加载指令,而不是从node_module,这种方式在AOT和JIT都能正常工作。

感谢大家的帮助。

UMD:https://unpkg.com/@neoprospecta/[email protected]/dist/bundles/angular-textarea-resize.umd.js

Plunker:https://plnkr.co/edit/omWp7OfFvaoTQgG0Xs48?p=preview

套餐:https://www.npmjs.com/package/@neoprospecta/angular-textarea-resize

这是我用来建设任务:

#!/usr/bin/env node 
'use strict'; 

const fs = require('fs'); 
const path = require('path'); 
const glob = require('glob'); 

/** 
* Simple Promiseify function that takes a Node API and return a version that supports promises. 
* We use promises instead of synchronized functions to make the process less I/O bound and 
* faster. It also simplify the code. 
*/ 
function promiseify(fn) { 
    return function() { 
    const args = [].slice.call(arguments, 0); 
    return new Promise((resolve, reject) => { 
     fn.apply(this, args.concat([function (err, value) { 
     if (err) { 
      reject(err); 
     } else { 
      resolve(value); 
     } 
     }])); 
    }); 
    }; 
} 

const readFile = promiseify(fs.readFile); 
const writeFile = promiseify(fs.writeFile); 
const outputDir = './inline-src'; 


function rmDir(dirPath) { 
    try { var files = fs.readdirSync(dirPath); } 
    catch(e) { return; } 
    if (files.length > 0) 
    for (var i = 0; i < files.length; i++) { 
     var filePath = dirPath + '/' + files[i]; 
     if (fs.statSync(filePath).isFile()) 
     fs.unlinkSync(filePath); 
     else 
     rmDir(filePath); 
    } 
    fs.rmdirSync(dirPath); 
}; 

function inlineResources(globs) { 
    if (typeof globs == 'string') { 
    globs = [globs]; 
    } 

    /** 
    * For every argument, inline the templates and styles under it and write the new file. 
    */ 
    return Promise.all(globs.map(pattern => { 
    if (pattern.indexOf('*') < 0) { 
     // Argument is a directory target, add glob patterns to include every files. 
     pattern = path.join(pattern, '**', '*'); 
    } 

    const files = glob.sync(pattern, {}) 
     .filter(name => /\.ts$/.test(name)); // Matches only JavaScript files. 

    rmDir(outputDir+''); 
    fs.mkdir(outputDir); 

    // Generate all files content with inlined templates. 
    return Promise.all(files.map(filePath => { 
     return readFile(filePath, 'utf-8') 
     .then(content => inlineResourcesFromString(content, url => { 
      return path.join(path.dirname(filePath), url); 
     })) 
     .then(content => { 
      var inlinePath = outputDir + '/' + filePath.replace(/^.*[\\\/]/, '') 
      writeFile(inlinePath, content); 
     }) 
     .catch(err => { 
      console.error('An error occurred: ', err); 
     }); 
    })); 
    })); 
} 

/** 
* Inline resources from a string content. 
* @param content {string} The source file's content. 
* @param urlResolver {Function} A resolver that takes a URL and return a path. 
* @returns {string} The content with resources inlined. 
*/ 
function inlineResourcesFromString(content, urlResolver) { 
    // Curry through the inlining functions. 
    return [ 
    inlineTemplate, 
    inlineStyle, 
    removeModuleId 
    ].reduce((content, fn) => fn(content, urlResolver), content); 
} 

if (require.main === module) { 
    inlineResources(process.argv.slice(2)); 
} 


/** 
* Inline the templates for a source file. Simply search for instances of `templateUrl: ...` and 
* replace with `template: ...` (with the content of the file included). 
* @param content {string} The source file's content. 
* @param urlResolver {Function} A resolver that takes a URL and return a path. 
* @return {string} The content with all templates inlined. 
*/ 
function inlineTemplate(content, urlResolver) { 
    return content.replace(/templateUrl:\s*'([^']+?\.html)'/g, function(m, templateUrl) { 
    const templateFile = urlResolver(templateUrl); 
    const templateContent = fs.readFileSync(templateFile, 'utf-8'); 
    const shortenedTemplate = templateContent 
     .replace(/([\n\r]\s*)+/gm, ' ') 
     .replace(/"/g, '\\"'); 
    return `template: "${shortenedTemplate}"`; 
    }); 
} 


/** 
* Inline the styles for a source file. Simply search for instances of `styleUrls: [...]` and 
* replace with `styles: [...]` (with the content of the file included). 
* @param urlResolver {Function} A resolver that takes a URL and return a path. 
* @param content {string} The source file's content. 
* @return {string} The content with all styles inlined. 
*/ 
function inlineStyle(content, urlResolver) { 
    return content.replace(/styleUrls:\s*(\[[\s\S]*?\])/gm, function(m, styleUrls) { 
    const urls = eval(styleUrls); 
    return 'styles: [' 
     + urls.map(styleUrl => { 
      const styleFile = urlResolver(styleUrl); 
      const styleContent = fs.readFileSync(styleFile, 'utf-8'); 
      const shortenedStyle = styleContent 
      .replace(/([\n\r]\s*)+/gm, ' ') 
      .replace(/"/g, '\\"'); 
      return `"${shortenedStyle}"`; 
     }) 
     .join(',\n') 
     + ']'; 
    }); 
} 


/** 
* Remove every mention of `moduleId: module.id`. 
* @param content {string} The source file's content. 
* @returns {string} The content with all moduleId: mentions removed. 
*/ 
function removeModuleId(content) { 
    return content.replace(/\s*moduleId:\s*module\.id\s*,?\s*/gm, ''); 
} 


module.exports = inlineResources; 
module.exports.inlineResourcesFromString = inlineResourcesFromString; 
+0

您的包中没有构造函数参数。你如何建立它? – yurzui

+0

我使用过这个软件包@ neoprospecta/angular-inline-resources。 – vinagreti

+0

问题是,即使没有构造函数,它为什么与--aot? – vinagreti

回答

1

我怀疑你忘了

"emitDecoratorMetadata": true 

在您的tsconfig.json

+0

非常感谢! – vinagreti

相关问题