지시문 npm 패키지를 만드는 중 문제가 있습니다.오류 : 지침의 모든 매개 변수를 해결할 수 없습니다.
@Component 용 패키지를 이미 만들었지 만 @Directive 용으로 만든 패키지가 처음입니다.
제가 직면 한 문제는 ng serve
을 실행할 때 빌드가 완료되었지만 페이지를로드 할 때 Error: Can't resolve all parameters for HighlightDirective
이 발생한다는 것입니다.
궁금한 점은 실행하면 ng serve --aot
문제가 나타나지 않는다는 것입니다.
따라서 패키지는 --AOT에서만 작동하며 JIT에서는 오류를 발생시킵니다.
5 월 - 사용자 지정 지시문을 파싱하기 전에 일부 패키지가 필요합니다. 다른 모듈이 필요한 패키지를로드하기 전에 지시문을로드하려고 시도하는 JIT에서는 발생하지 않습니다.
나는 문제를 보여줄 플 런커를 만들었고 내 코드를 볼 수 있도록 패키지 URL을 남겨두고 있습니다.
텍스트 영역-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
이고, 지시문 sintax가 올바른지 확인하기 위해 angular.io 문서에서 내 지시문을 대체했기 때문에
textarea-resize.directive
이라는 파일 이름이되었습니다.
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
패키지 :
#!/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;
번들에 생성자 매개 변수가 없습니다. 그것을 어떻게 구축합니까? – yurzui
이 패키지는 @ neoprospecta/angular-inline-resources 패키지에 사용되었습니다. – vinagreti
질문은 생성자가 없어도 왜 --aot와 함께 작동합니까? – vinagreti