PegJS と requirejs を使用してプロジェクトをテストしようとしています。AMDモジュール(定義)として実装されたソースファイルがいくつかあり、require APIを介してロードされます。ディレクトリ構造の下:
js/
somefile.js
main.js
parser.js
test/
parser.spec.js
PegJS 文法ファイルをロードし、PegJS を使用してペグ パーサーを作成するためのparser.jsモジュールを作成しました。
define(function() {
'use strict';
var PEG = require('pegjs');
var grammarFile = 'grammar.peg'
return {
parse: function(fs, content, debug) {
var grammar = fs.readFileSync(grammarFile, 'utf8').toString();
// Build parser from grammar
var parser = PEG.buildParser(grammar, { trace: debug });
[...]
これは、ノードを使用してコマンドラインで実行される main.js で正常に機能します。ここで、カルマ、ジャスミン、PhantomJS を使用してプロジェクトをテストしたいと考えています。次のようなkarma.conf.jsがあります。
frameworks: ['jasmine', 'requirejs'],
files: [
{ pattern: './test/**/*.spec.js', included: false },
{ pattern: './js/**/*.js', included: false},
'./test/test-main.js',
],
また、次のように構成されたtest-main.jsという名前のブートストラップ ファイルが必要です。
'use strict';
var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;
// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function(file) {
console.log(file);
if (TEST_REGEXP.test(file)) {
// Normalize paths to RequireJS module names.
// If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
// then do not normalize the paths
var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '');
allTestFiles.push(file);
}
});
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: '/base/js',
// dynamically load all test files
deps: allTestFiles,
// we have to kickoff jasmine, as it is asynchronous
callback: window.__karma__.start
});
ここで、テスト ( grunt karma
) を起動すると、次のエラーが発生しました。
PhantomJS 1.9.8 (Linux 0.0.0) ERROR: Error{message: 'Module name "pegjs" has not been loaded yet for context: _. Use require([])
そこで、Karma によってロードされたファイルに pegjs をこのようにkarma.conf.jsとして含めようとしました。
files: [
{ pattern: 'node_modules/pegjs/lib/**/*.js', included: true },
{ pattern: './test/**/*.spec.js', included: false },
{ pattern: './js/**/*.js', included: false},
'./test/test-main.js'
],
これを行うと、まだエラーが発生します。
Error: Module name "utils/arrays" has not been loaded yet for context: _. Use require([])
pegjs モジュールの中を見ると、確かに arrays.js ファイルがあります。
compiler/
compiler.js
grammar-error.js
parser.js
peg.js
utils/
arrays.js
classes.js
objects.js
したがって、配列も含めようとしています:
files: [
{ pattern: 'node_modules/pegjs/lib/utils/arrays.js', included: true },
{ pattern: 'node_modules/pegjs/lib/**/*.js', included: true },
{ pattern: './test/**/*.spec.js', included: false },
{ pattern: './js/**/*.js', included: false},
'./test/test-main.js'
],
私は得る:
ReferenceError: Can't find variable: module
at /blabla/node_modules/pegjs/lib/utils/arrays.js:108
なぜなら:
108 module.exports = arrays;
そこで、npm モジュールをロードする代わりに、bower モジュールを次のようにロードしようとしました。
files: [
{ pattern: 'bower_components/pegjs/peg-0.9.0.js', included: true },
{ pattern: './test/**/*.spec.js', included: false },
{ pattern: './js/**/*.js', included: false},
'./test/test-main.js'
],
そして、ここに再び行きます:
PhantomJS 1.9.8 (Linux 0.0.0) ERROR: Error{message: 'Module name "pegjs" has not been loaded yet for context: _. Use require([])
また、karma で生成された Web ページに pegjs を含めないようにしました。
files: [
{ pattern: 'bower_components/pegjs/peg-0.9.0.js', included: false },
{ pattern: './test/**/*.spec.js', included: false },
{ pattern: './js/**/*.js', included: false},
'./test/test-main.js'
],
しかし、それは失敗します:
PhantomJS 1.9.8 (Linux 0.0.0) ERROR: 'There is no timestamp for /base/bower_components/pegjs/peg-0.9.0!'
bower_component フォルダーを js フォルダー内に配置しようとしましたが、うまくいきませんでした。
だから、ここから行くべきかどうかはわかりません... Googleまたはここで関連するものが見つかりませんでした。カルマでrequirejs / pegjsを使用するのは特定の問題のようです...どんなアイデアでも大歓迎です。
次のダンの答えを更新してください:
そこで、 parser.jsで同期の require から非同期の require に切り替えます。
define(['../bower_components/pegjs/peg-0.9.0'], function(PEG) {
'use strict';
var grammarFile = 'grammar.peg'
return {
parse: function(fs, content, debug) {
var grammar = fs.readFileSync(grammarFile, 'utf8').toString();
// Build parser from grammar
var parser = PEG.buildParser(grammar, { trace: debug });
[...]
karma.conf.js にpegjs bower コンポーネントを含めようとしました:
{ pattern: 'bower_components/pegjs/peg-0.9.0.js', included: false },
または含まない:
{ pattern: 'bower_components/pegjs/peg-0.9.0.js', included: true },
ただし、常に同じエラーが発生します。
Error: Script error for "/blabla/bower_components/pegjs/peg-0.9.0", needed by: /blabla/js/parser.js
http://requirejs.org/docs/errors.html#scripterror
at /blabla/node_modules/requirejs/require.js:140
はい、ファイルが存在します:
$ file /home/aa024149/share/logofrjs/bower_components/pegjs/peg-0.9.0.js
/blabla/bower_components/pegjs/peg-0.9.0.js: ASCII text, with very long lines
UPDATE2 : 最終的に理解し、許容できる解決策を見つけました。