Absolute or relative "templateUrls" for angular components

Can someone please help me in this dead 1 vs 2?

1) Angular project as an AoT in production. This required my source code to be changed to have templateUrl and styleUrls, which are relative to the component.ts file.

2) Angular karma as JiT for unit tests. This required my source code to be changed to have templateUrl and styleUrls Absolute , or unit test would call 404 looking for the .html file.

I would like to avoid preserving the relative AND absolute path in the source code.

What are my options here? What is the best practice?

(I use WEBPACK with aot and Karma, NOT angular-cli)

Thanks!!

UPDATE: we will also consider converting to angular-cli, but this is a huge project, and for us it is a blocker if someone knows the trick that angular-cli uses to remove this. or even a workaround so we can return our unit tests!

I need to know a trick to run WITH AoT unit tests or at least ALONG SIDE AoT (in other words, run production and jit unit tests with one set of templates)

Thanks again!

PS .. This worked fine without AoT (with absolute URLs), but switching to AoT (with URLs relative to the component file) blocked us.

UPDATE 2: (including all my configuration files) if I need to create another configuration file to run the tests (which makes sense), but I would like to know what is the β€œmagic” that the test configuration requires to run the JiT components, now, when my urls are relative.

webpack.config.js

let webpack = require('webpack'); let path = require('path'); let aot = require('@ngtools/webpack'); module.exports = { entry: { main: './Angular/main' }, output: { path: __dirname, filename: './dist/smartcommand-[name].min.js', // Lazy load modules by route & chunk chunkFilename: './dist/smartcommand-[name].chunk.[hash].min.js' }, resolve: { extensions: ['.ts', '.js'], modules: [ path.resolve('./'), path.resolve('./node_modules') ], alias: { 'ng2-charts/charts/charts': 'node_modules/ng2-charts/bundles/ng2-charts.umd.min.js' //'ng2-dragula': 'node_modules/ng2-dragula/bundles/ng2-dragula.umd.min.js' } }, module: { rules: [ // Ahead of Time Compilation { test: /\.ts$/, loader: '@ngtools/webpack', exclude: [/\.(spec)\.ts$/] }, // AoT requires all files to be loaded { test: /\.html$/, loader: 'html-loader' }, { test: /\.css$/, loader: 'raw-loader' }, { test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, loader: 'file-loader', options: { name: '[path][name].[ext]' } } ] }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'main' }), // Ahead of Time Plugin new aot.AngularCompilerPlugin({ tsConfigPath: path.resolve('./Angular/tsconfig.json'), entryModule: path.resolve('./Angular/_app.module#SmartCommandModule') // Use this setting to turn off AoT //,skipCodeGeneration: true }), // Only load the necessary locales for moment new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en|es/) ], // Minimize webpack console output stats: { assets: false, children: false } }; 

karma.config.js

 /* Karma Configuration */ 'use strict'; module.exports = function (config) { let appBase = 'Angular/'; // transpiled app JS and map files config.set({ plugins: [ 'karma-jasmine', 'karma-jasmine-html-reporter', //'karma-chrome-launcher', 'karma-firefox-launcher', // preprocessors 'karma-webpack', 'karma-sourcemap-loader', // show proper (un-bundled) stack traces 'karma-coverage', // capture unit test code coverage 'karma-trx-reporter' // report coverage in VSTS ], // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine'], // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher //browsers: ['Chrome'], browsers: ['Firefox'], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { 'karma-test-shim.js': ['webpack', 'coverage'] // for debugging the tests //'karma-test-shim.js': ['webpack', 'sourcemap'] }, // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '', // list of files / patterns to load in the browser files: [ // polyfills 'node_modules/core-js/client/shim.js', 'Scripts/jquery-3.1.1.min.js', 'Scripts/jquery-ui-1.12.1.min.js', 'node_modules/moment/moment.js', 'node_modules/leaflet/dist/leaflet.js', 'node_modules/nipplejs/dist/nipplejs.js', 'node_modules/zone.js/dist/zone.js', 'node_modules/zone.js/dist/long-stack-trace-zone.js', 'node_modules/zone.js/dist/proxy.js', 'node_modules/zone.js/dist/sync-test.js', 'node_modules/zone.js/dist/jasmine-patch.js', 'node_modules/zone.js/dist/async-test.js', 'node_modules/zone.js/dist/fake-async-test.js', // rxJS { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, // other dependencies { pattern: 'node_modules/applicationinsights-js/**/*.js', included: false, watched: false }, { pattern: 'node_modules/applicationinsights-js/**/*.js.map', included: false, watched: false }, { pattern: 'node_modules/ng2-charts/**/*.js', included: false, watched: false }, { pattern: 'node_modules/ng2-charts/**/*.js.map', included: false, watched: false }, 'node_modules/chart.js/dist/Chart.bundle.js', { pattern: 'node_modules/primeng/**/*.js', included: false, watched: false }, { pattern: 'node_modules/ngx-slick/**/*.js', included: false, watched: false }, { pattern: 'node_modules/ng2-dragula/**/*.js', included: false, watched: false }, { pattern: 'node_modules/ng2-dragula/**/*.js.map', included: false, watched: false }, // our SmartCommand bundle 'dist/smartcommand-main.min.js', // our Karma tests { pattern: 'karma-test-shim.js', included: true, watched: true }, // paths for debugging with source maps in dev tools { pattern: appBase + '**/*.ts', included: false, watched: false }, { pattern: appBase + '**/*.js.map', included: false, watched: false }, // our assets (HTML & CSS) paths loaded via Angular component compiler { pattern: appBase + '**/*.html', included: false, watched: true }, { pattern: appBase + '**/*.css', included: false, watched: true }, { pattern: 'Content/*.css', included: true, watched: false }, { pattern: 'Content/*.css.map', included: false, watched: false }, { pattern: 'Content/Images/**/*', included: false, watched: false }, { pattern: 'Content/images/**/*', included: false, watched: false } ], // proxied base paths for loading assets proxies: { // required for component assets fetched by Angular compiler '/Angular/': '/base/Angular/', '/Content/': '/base/Content/' }, // test results reporter to use // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['progress', 'kjhtml', 'coverage', 'trx'], // karma code coverage coverageReporter: { // specify a common output directory dir: 'coverage', reporters: [ // reporters not supporting the `file` property { type: 'html', subdir: 'report-html' }, { type: 'lcov', subdir: 'report-lcov' }, // reporters supporting the `file` property, use `subdir` to directly // output them in the `dir` directory { type: 'cobertura', subdir: '.', file: 'cobertura.txt' }, { type: 'lcovonly', subdir: '.', file: 'report-lcovonly.txt' }, { type: 'teamcity', subdir: '.', file: 'teamcity.txt' }, { type: 'text', subdir: '.', file: 'text.txt' }, { type: 'text-summary', subdir: '.', file: 'text-summary.txt' } ] }, // get code coverage in VSTS trxReporter: { outputFile: 'test-results.trx', shortTestName: false }, // web server port port: 9876, // enable / disable colors in the output (reporters and logs) colors: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, // enable / disable watching file and executing tests whenever any file changes autoWatch: true, // continuous integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: false, // concurrency level // how many browsers should be started simultaneous concurrency: Infinity, client: { captureConsole: false, // set to true if you need console output builtPaths: [appBase], // add more spec base paths as needed clearContext: false // leave Jasmine Spec Runner output visible in browser }, // workaround for disconnects browserDisconnectTolerance: 5, browserNoActivityTimeout: 50000 }); }; 

test karma

 // 'No stack trace' is usually best for app testing. Error.stackTraceLimit = 0; // Uncomment to get full stacktrace output. Sometimes helpful, usually not. //Error.stackTraceLimit = Infinity; // Import all .spec.js files in our Angular folder let appContext = require.context('./Angular', true, /\.spec\.js$/); appContext.keys().forEach(appContext); // Start the Test Environment let testing = require('@angular/core/testing'); let browser = require('@angular/platform-browser-dynamic/testing'); testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting()); 
+5
source share
1 answer

Here is the problem I am seeing. In fact, you are using two different Webpack configurations. Obviously there is your webpack.config.js that is installed for AoT.

However, when you start Karma, you use a different, different configuration. The karma-webpack provides a Webpack instance that runs in the Karma process with its own configuration. If you yourself do not write the code in karma.config.js to read webpack.config.js , then Karma will completely ignore this file. So effective when you use Karma, you are working with a different Webpack configuration. The problem is that your configuration is currently empty, which means that Angular processes templateUrl and styleUrls "raw", and you get the results you get.

You need to configure Webpack with a loader that will handle templateUrl and stylesUrls so that Webpack will handle them. For this, I used angular2-template-loader .

Looking at your configuration, it seems that by the time Karma saw your files, they were all transcribed in JavaScript. Typically, angular2-template-loader used in TypeScript files, but since it does its work using regular expressions, it also works with JavaScript files.

I expect that adding a Webpack configuration using angular2-template-loader to your karma.config.js should work, and customize for the needs specific to your project:

 webpack: { module: { loaders: [ { test: /\.js$/, loaders: ['angular2-template-loader'], // exclude: [...] You may want to exclude your test files here // to save some build time. }, // etc. with raw-loader, html-loader and file-loader as needed. ]}, } 
+1
source

Source: https://habr.com/ru/post/1273691/


All Articles