systemjs: mapping everything else to node_modules - systemjs

I am having trouble getting systemjs to work so it resolves node modules.
I have the following in my index.html:
<script src="./system.config.js"></script>
<script>
System.import('blast/test')
.then(null, console.error.bind(console));
</script>
This is my configuration:
System.config({
baseUrl: '/',
packages: {
'app': {
defaultExtension: 'js',
}
},
packageConfigPaths: ['./node_modules/*/package.json'],
paths: {
'blast/*': 'app/*'
}
});
This works fine so far. However, I want to be able to also resolve node modules like lodash. So I set paths to this:
paths: {
'blast/*': 'app/*'
'*': './node_modules/*'
}
Now I can import lodash fine, but when importing blast/test I get the error /app/test 404 (not found). It seems, the package configuration isn't used anymore, this .js isn't appended. Anyone got any hints how to resolve this? I am using SystemJs 0.19.25 Standard.
Thanks, Robin

Try using map configuration here rather for your local package -
System.config({
map: {
blast: './app'
}
});
The ./ is necessary to distinguish the URL space from becoming the node_modules/app path (probably the reason you used paths here to begin with?)
It's also advisable to use baseURL: 'node_modules' instead of a wildcard paths entry (and they pretty much amount to the same thing).

Related

Requiring config.js file in VSCode extension with absolute path (e.g. "C:\...") does not work

I am developing the Argdown VSCode extension. The Argdown parser can be configured using either argdown.config.json files or argdown.config.js files exporting a config object. Using Javascript files is the easiest way to allow users to add custom plugins to the Argdown parser.
If the user tells the parser to use a Javascript file, the file is loaded using import-fresh, (which uses node's require, but deletes the cached version.
Using the Argdown commandline tool (#argdown/cli) this works fine, but in the VSCode extension the module of the config file can not be found. The extension is using absolute file paths to require the config module (e.g. "C:\Users\my-username\projects\my-argdown-project\argdown.config.js"). These paths work with import-fresh outside of the VScode extension.
Is there a security restriction for VSCode extensions that does not allow to require modules with absolute file paths? Or is there some other reason why this does not work?
This was not related to VSCode. The problem was caused by bundling up import-fresh with webpack. I thought that webpack would ignore dynamic imports, but it did not.
I was lucky: Since last month, webpack supports "magic comments" for require (not only for import). So I can use:
require(/* webpackIgnore: true */ file);
You have to activate magic comments support in your webpack config:
module.exports = {
parser: {
javascript: {
commonjsMagicComments: true,
},
},
}
Now the next question is how to add the magic comments to the import-fresh package. For that I used the string-replace-loader:
module.exports = {
module: {
rules: {
{
enforce: "pre",
test: /import-fresh[\/\\]index\.js/,
loader: "string-replace-loader",
options: {
search:
"return parent === undefined ? require(filePath) : parent.require(filePath);",
replace:
"return parent === undefined ? require(/* webpackIgnore: true */ filePath) : parent.require(/* webpackIgnore: true */ filePath);",
},
},
}
}
}
After that, I could load the argdown.config.js files again, even after bundling everything with webpack.

Loading library.js from bad path

I have updated OpenUI5 of my project from 1.42.7 to 1.60.12 (LTS)
If I try to run the app with the new version, I have this error:
Uncaught Error: failed to load 'sap/ui/core/library.js' from resources/sap/ui/core/library.js: 404 - Not Found**
The tree structure of my project has OpenUI5 files into resources/openui path:
In index.html, I set src in this mode:
<script id="sap-ui-bootstrap"
src="resources/openui/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-libs="sap.m"
data-sap-ui-preload=""
data-sap-ui-resourceroots='{
"ui5bp": "./",
"model": "./model"
}'
></script>
It seems that the first call of sap-ui-core.js finishes correctly (from Webcontent/resources/openui) but then the call of library.js is called from Webcontent/resources/, not from Webcontent/resources/openui.
In 1.42 version, all works fine.
Note: if I try to retrieve OpenUI5 resources from CDN, all works fine...
src="https://openui5.hana.ondemand.com/1.60.12/resources/sap-ui-core.js"
Option 1 (recommended)
Move the UI5 resources to the resources folder directly underneath.
˅ 📂resources
˃ 📁openui
˅ 📂sap
˃ 📁base
˃ 📁f
˃ 📁m
...
...
sap-ui-core.js
According to the topic Bootstrapping: Loading and Initializing - Initialization Process, UI5 will try to fetch library resources from the following path by default:
Library bootstrap file /<context-path>/resources/<library-name>/library(-preload).js
Having a deviating path (/resources/openui/<library-name>/ in between) makes fetching the library files incompatible with default settings.
Option 2 (without changing the folder structure)
Define a new default base URL in index.html as early as possible. E.g. via the global configuration object:
<script>
window["sap-ui-config"] = {
resourceRoots: {
"": "./resources/openui/", // <-- new base URL
"ui5bp": "./",
// ...
},
libs: "sap.ui.core, sap.m",
async: true,
theme: "sap_belize",
compatVersion: "edge",
// ...
};
</script>
<script id="sap-ui-bootstrap" src="resources/openui/sap-ui-core.js"></script>
This one works too as resolving "" will always work as a fallback
Note that the empty prefix ("") will always match and thus serves as a fallback for any search. source

How can I use my webpack's html-loader imports in Jest tests?

I am just getting started with the Jest test framework and while straight up unit tests work fine, I am having massive issues testing any component that in its module (ES module via babel+webpack) requires a HTML file.
Here is an example:
import './errorHandler.scss';
import template from './errorHandler.tmpl';
class ErrorHandler {
...
I am loading the component specific SCSS file which I have set in Jest's package.json config to return an empty object but when Jest tries to run the import template from './errorHandler.tmpl'; line it breaks saying:
/Users/jannis/Sites/my-app/src/scripts/errorHandler/errorHandler.tmpl.html:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<div class="overlay--top">
^
SyntaxError: Unexpected token <
at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:284:10)
My Jest config from package.json is as follows:
"jest": {
"setupTestFrameworkScriptFile": "<rootDir>/test/setupFile.js",
"moduleDirectories": ["node_modules"],
"moduleFileExtensions": ["js", "json", "html", "scss"],
"moduleNameMapper": {
"^.+\\.scss$": "<rootDir>/test/styleMock.js"
}
}
It seems that the webpack html-loader is not working correctly with Jest but I can't find any solution on how to fix this.
Does anyone know how I can make these html-loader imports work in my tests? They load my lodash template markup and i'd rather not have these at times massive HTML chunks in my .js file so i can omit the import template from x part.
PS: This is not a react project, just plain webpack, babel, es6.
I encountered this specific problem recently and creating your own transform preprocesser will solve it. This was my set up:
package.json
"jest": {
"moduleFileExtensions": [
"js",
"html"
],
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.html$": "<rootDir>/test/utils/htmlLoader.js"
}
}
NOTE: babel-jest is normally included by default, but if you specify a custom transform preprocessor, you seem to have to include it manually.
test/utils/htmlLoader.js:
const htmlLoader = require('html-loader');
module.exports = {
process(src, filename, config, options) {
return htmlLoader(src);
}
}
A bit late to the party, but wanted to add that there is also this html-loader-jest npm package out there to do this if you wanted to go that route.
Once you npm install it you will add it to your jest configuration with
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.html?$": "html-loader-jest"
}
For Jest > 28.x.x with html-loader:
Create a custom transformer as documented here.
jest/html-loader.js
const htmlLoader = require("html-loader");
module.exports = {
process(sourceText) {
return {
code: `module.exports = ${htmlLoader(sourceText)};`,
};
},
};
Add it to your jest config.
jest.config.js
...
// A map from regular expressions to paths to transformers
transform: {
"^.+\\.html$": "<rootDir>/jest/html-loader.js",
},
...
It will fix the error : Invalid return value: process() or/and processAsync() method of code transformer found at "<PATH>" should return an object or a Promise resolving to an object.
Maybe your own preprocessor file will be the solution:
ScriptPreprocessor
Custom-preprocessors
scriptpreprocessor: The path to a module that provides a synchronous function from pre-processing source files. For example, if you wanted to be able to use a new language feature in your modules or tests that isn't yet supported by node (like, for example, ES6 classes), you might plug in one of many transpilers that compile ES6 to ES5 here.
I created my own preprocessor when I had a problems with my tests after added transform-decorators-legacy to my webpack module loaders.
html-loader-jest doesn't work for me. My workaround for this:
"transform": {
'\\.(html)$': '<rootDir>/htmlTemplateMock.html'
}
htmlTemplateMock.html is empty file
For Jest 28+ you can use jest-html-loader to make Jest work with code that requires HTML files.
npm install --save-dev jest-html-loader
In your jest config, add it as a transformer for .HTML files:
"transform": {
"^.+\\.html?$": "jest-html-loader"
},

jspm not loading bundles with --inject

Been experimenting with jspm and systemjs over the weekend. Everything is working fine except for the bundling jspm offers. I can load individual files, but jsmp refuses to load the bundle file (which is optimized).
I'm creating the bundle file using:
jspm bundle lib/login assets/js/1-login.js --inject
This updates the config.js file which looks like:
System.config({
baseURL: "/",
defaultJSExtensions: true,
transpiler: "babel",
babelOptions: {
"optional": [
"optimisation.modules.system"
]
},
paths: {
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*"
},
bundles: {
"1-login.js": [
"lib/login.js",
"lib/sample.js"
]
},
map: {....}
});
lib/login.js
import * as sample from 'lib/sample'
export function test() {
sample.testMethod();
}
lib/sample.js
import $ from 'jquery'
export function testMethod( ) {
console.log( $('body') );
}
So, according to the jsmp docs:
As soon as one of these modules is requested, the request is intercepted and the bundle is loaded dynamically first, before continuing with the module load.
It's my understanding that running
System.import('lib/login.js');
should load the bundle (and optimised file), but is doesn't - it just loads the actual file. What am I missing here? And as a bonus question, why is jquery not in the bundle list?
Well, figured out where I went wrong.
I keep all the generated assets in assets/js, but in my config.json I didn't change the baseUrl to reflect this. I did in fact have the baseUrl set correctly in package.json, which is why jspm didn't throw a lot of errors.
This was the same reason jquery wasn't loading, so problem solved :)

django-tastypie-swagger not serving Swagger's JS/CSS files

I have a fresh install of django-tastypie and django-tastypie-swagger.
http://localhost:8000/tasty/doc/ serves the necessary HTML, but doesn't pull in any of the CSS or JS that's needed to make it work.
http://localhost:8000/tasty/doc/resources/ works and shows:
{
basePath: "http://localhost:8000/tasty/doc/schema/",
apis: [
{
path: "/snap"
},
{
path: "/user"
}
],
apiVersion: "0.1",
swaggerVersion: "1.1"
}
But all the others (/schema/ and the static files) return 404 errors.
I had the same problem you had and solved it by creating a file under my project templates directory on the following path: templates/tastypie_swagger with the content of this file:
Note that the problem is caused by the STATIC_URL variable, which is misunderstood, I replaced that variable with my project url, and it worked perfect.
For anyone who encounter this problem in the future ... you might want to perform the following command after installing django-tastypie
python manage.py collectstatic --noinput
I had the same problem. Simple fix add 'django.core.context_processors.static' to 'context_processors' in settings.py. Than STATIC_URL will work.