Vue DOM image won't show correctly - javascript

I'm using the Vue framework and creating an image using the DomUtil.Create function. In this image I want to dynamically write the source to this image. But the image won't show to the user.
I put a normal image on the page using the <img> tag and it works here. Only when creating the DOM element it doesn't work. I put the path hard coded in here so it is certain that the path is correct.
var img = L.DomUtil.create("img", "popUpImg", divImg);
img.src = '#/assets/pictures/1.png';

Use require()
When binding to a project path / filename, use require:
require('#/assets/pictures/1.png');
If you use project asset paths and filenames in Vue CLI, Webpack actually renames them while bundling. Vue CLI quietly takes care of this if you use a string path for img src in the template. But in any other situation, you need to manually use Webpack's require to give the correct path and filename at runtime.
- Note: You can npm run build and then check the dist > img folder to see the renaming for yourself. -
Can I use a variable with require()?
When using a variable path/filename, require needs some assistance. You must hard code at least the first portion of the path as a string.
For example, this works:
const filename = '1.png';
require('#/assets/pictures/' + filename); // <-- The string is needed
This works too:
const path = 'assets/pictures/1.png';
require('#/' + path); // <-- This is good enough too
But this would not work:
const fullpath = '#/assets/pictures/1.png';
require(fullpath); // <-- No. Can't infer the path from a variable only
Read more in the Vue Loader docs

Related

Node requiring directory rather than specific file

Are these two statements equivalent?
const deviceModule = require('..').device;
const deviceModule = require('../device');
I thought require needed a module (with our without path) as the parameter. How is it that a directory can be provided and what does the .device do?
Thanks to anyone who can help me understand node.js and javascript better.
require('..').device requires index.js from the parent directory, and then gets device from that file.
So if you had the following structure:
- index.js
- /foo
- - bar.js
With index.js having the following:
module.exports = {
device: "baz"
};
Then require("..").device in bar.js would give you "baz".
Here is the specification for loading a directory:
LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
a. Parse X/package.json, and look for "main" field.
b. let M = X + (json main field)
c. LOAD_AS_FILE(M)
2. If X/index.js is a file, load X/index.js as JavaScript text. STOP
3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
4. If X/index.node is a file, load X/index.node as binary addon. STOP
So in your example, it will:
look for package.json and get the main property, and then load that if it exists
If step 1 does not exist, it will load index.js if it exists
If step 2 does not exist, it will load index.json if it exists
If step 4 does not exist, it will load index.node if it exists
You can use module require-file-directory.
1- Helps to require all the files only with name. No need to give absolute path of files.
2- Multiple files at a time.

Browserify: Uncaught error when requiring js file by path created from string concatenation

I am using browesify for client side app. I have files maps.js and directions.js sitting besides my index.js file, and inside my index.js, I have a function getPageName() which returns the name of the file that I should "require". When I try to do
var pageName = getPageName();
var page;
if (pageName === 'maps') {
page = require('./maps');
} else if (pageName === 'directions') {
page = require('./directions');
}
it works fine. But when I instead try to use following trick to minimize my code,
var pageName = getPageName();
var page = require('./' + pageName);
I get error Uncaught Error: Cannot find module './maps' in console log in Chrome. Why does it not work when I use string concatenation but works when I use pass the path explicitly?
That is a limitation of Browserify and similar type libraries. In order to do the require() the library has to examine the js code as a string, and determine file paths before the code is run. This means file paths have to be static in order for it to be picked up.
https://github.com/substack/node-browserify/issues/377
Browserify can only analyze static requires. It is not in the scope of
browserify to handle dynamic requires

Is it possible to require modules from outside of your project directory without relative paths?

I'm trying to build a local library of JS modules to use in Node projects.
If a new project lives in /Users/me/projects/path/to/new/project/ and my library files are located in /Users/me/projects/library/*.js is there a way to access those files without using a relative path?
In /Users/me/projects/path/to/new/project/app.js you can require foo.js like so:
var foo = require('../../../../../library/foo') and that will work but that's clunky and if files move you'd have to update your relative paths.
I've tried requireFrom and app-module-path with no luck as they are relative to a project root.
Any ideas for how to require files from outside of your project dir?
Thanks in advance!
var librarypath = '/Users/me/projects/library/';
// or if you prefer...
// var librarypath = '../../../../../library/';
var foo = require(librarypath + 'foo.js');
... or dressed up a bit more ...
function requirelib(lib){ return require('/Users/me/projects/library/'+lib+'.js'); }
var foo = requirelib('foo');
var bar = requirelib('bar');
I had the same problem many times. This can be solved by using the basetag npm package. It doesn't have to be required itself, only installed as it creates a symlink inside node_modules to your base path.
const localFile = require('$/local/file')
// instead of
const localFile = require('../../local/file')
Using the $/... prefix will always reference files relative to your apps root directory.
Disclaimer: I created basetag to solve this problem

Using Crypto.js in meteor

I am trying to include some crypto.js libraries in a meteor js app (meteor version 0.6.4.1).
http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha256.js
http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js
When I copy and paste the contents into the server/main.js file it works fine, but this makes it very un-readable.
When I put the libraries in separate files in the server directory (I also tried placing them in the lib directory) I get the error ReferenceError: CryptoJS is not defined.
gist of server/main.js:
Meteor.methods({
encrypt:function(bundleID){
return CryptoJS.HmacSHA256(string, 'something');
}
});
I also tried changing the first line of the hmac-sha256.js file from
var CryptoJS=CryptoJS||function(h,s){...
to:
CryptoJS=CryptoJS||function(h,s){...
to make it global, but this also did not work. How do I include this library properly?
In your application dir create folder 'packages/cryptojs' and put there files:
hmac-sha256.js
enc-base64-min.js
package.js
packages / cryptojs / package.js:
Package.describe({
summary: "CryptoJS"
});
Package.on_use(function (api, where) {
api.add_files(['hmac-sha256.js'], ['client','server']);
api.add_files(['enc-base64-min.js'], ['client','server']);
});
You need to modify hmac-sha256.js by changing beginning of line 7 from:
var CryptoJS=CryptoJS||function(h,s){
to:
CryptoJS=function(h,s){
After that, you can use it:
var hash = CryptoJS.HmacSHA256("Message", "secret");
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
console.log(hashInBase64)
Example source
I followed as parhelium's guide, but still not work, then I found new way to fix this issue:
Just replace line 7 in hmac-sha512.js to this one to globalize CryptoJS object:
this.CryptoJS=this.CryptoJS
Fix the same for other cryptojs. To use with Base64, you must make sure the base64.js is loaded after other libraries.
The reason this is happening is due to the variable scoping in meteor. Try putting the cryptojs library files in /server/compatibility. This way the cryptojs library can be accessed in other files.
You could also get it working without putting it in /compatibility by removing the var used in the cryptojs source files. The thing is if you do this its harder to keep the files up to date.

How to set a including path in the Gjs code?

As i could see, the Gjs imports, loads only /usr/share/gjs-1.0 and /usr/lib/gjs-1.0 by default. I want to modularize an application, like we can do with node, but i must find modules relative to the script file.
I found this two ways to add include paths:
gjs --include-path=my-modules my-script.js
GJS_PATH=my-modules gjs my-script.js
...but both are related to the current directory, not to the file (obliviously), and they needed to be declared on the command line, making this unnecessarily complex.
How can i set a including path in the Gjs code? (So i can make this relative to the file)
Or... There is another way to import files from anywhere, like in python?
(Please, you don't need to propose to use a shellscript launcher to solve the --include-path and GJS_PATH problem. That is obvious, but less powerful. If we do not have a better solution, we survive with that.)
You need to set or modify imports.searchPath (which is not obvious because it doesn't show up with for (x in imports)print(x)). So this:
imports.searchPath.unshift('.');
var foo = imports.foo;
imports the file “foo.js” as the foo object.
This is compatible with Seed, although there imports knows it has a searchPath.
(Earlier versions of this answer were substantially less accurate and more inflammatory. Sorry).
As Douglas says, you do need to modify imports.searchPath to include your library location. Using . is simple, but depends on the files always being run from the same directory location. Unfortunately finding the directory of the currently executing script is a huge hack. Here's how Gnome Shell does it for the extensions API
I've adapted this into the following function for general use:
const Gio = imports.gi.Gio;
function getCurrentFile() {
let stack = (new Error()).stack;
// Assuming we're importing this directly from an extension (and we shouldn't
// ever not be), its UUID should be directly in the path here.
let stackLine = stack.split('\n')[1];
if (!stackLine)
throw new Error('Could not find current file');
// The stack line is like:
// init([object Object])#/home/user/data/gnome-shell/extensions/u#u.id/prefs.js:8
//
// In the case that we're importing from
// module scope, the first field is blank:
// #/home/user/data/gnome-shell/extensions/u#u.id/prefs.js:8
let match = new RegExp('#(.+):\\d+').exec(stackLine);
if (!match)
throw new Error('Could not find current file');
let path = match[1];
let file = Gio.File.new_for_path(path);
return [file.get_path(), file.get_parent().get_path(), file.get_basename()];
}
Here's how you might use it from your entry point file app.js, after defining the getCurrentFile function:
let file_info = getCurrentFile();
// define library location relative to entry point file
const LIB_PATH = file_info[1] + '/lib';
// then add it to the imports search path
imports.searchPath.unshift(LIB_PATH);
Wee! now importing our libraries is super-easy:
// import your app libraries (if they were in lib/app_name)
const Core = imports.app_name.core;

Categories

Resources