Reading txt files in Vue without Webpack - javascript

I have a file in #/assets called data.txt. Apparently, I'm unable to import Data from "#/assets/data.txt" and then create a function
computed: {
readFile: function(){
let reader = new FileReader();
reader.readAsText(Data)
return reader.result
}
}
because I can only import json and not txt without installing Webpack, and then configuring raw-loader, which seems like a massively complicated endeavor to read a simple text file. I also can't explicitly write reader.readAsText("./src/assets/data.txt") because I get an error of TypeError: Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'.
I know that I can circumvent this problem by simply making the text file into a json file and adding the line export const data="...", but, again, it seems like a rather circuitous solution to simply read a txt file.
(And I am aware of https://stackoverflow.com/a/54703169/376936, which is confusing to me, because I don't have a vue.config.js, which may be an entirely different problem, but it still doesn't explain why Vue can't read a simple text file without multiple steps. It seems like it's the very simple actions in Vue that cause the most confusion.)
Am I missing something very simple and basic?

Related

How can a page call a function from a javascript file that uses Require()?

Newbie coder here. By cobbling together tutorials, I created a .js module that uses Google's API to return the value of a cell in my Google Sheet.
The module, sheetsReader.js includes these two require lines at the top:
const {google} = require('googleapis');
let privatekey = require('../../config/privatekey.json');
And it defines a function, getCell(), that returns the value of whatever cell is passed to it as the argument—e.g. getCell('A6')
It works perfectly when I run it in node terminal. But I want to access this function in my index.html, so I can display a cell value on the page. (I'm aware there may be better ways to accomplish this, but I'm trying to plug this spreadsheet data into an existing page.)
To export the function, in sheetsReader.js, I have:
module.exports.getCell = getCell;
And to import in index.html I put in the header:
<script>
import * as getCell from './js/sheetsReader.js'
</script>
However, when I open the page, it fails to load properly because:
Uncaught ReferenceError: require is not defined
at sheetsReader.js:1
I know now that require() does not work browser-side. I've tried to solve by using browserify, requirejs, and all sorts of other fixes, but none seem to work for an html page.
I feel like I'm probably missing something very fundamental here—so I apologize! I learned to set up a server just so I could use the Google API to read a spreadsheet... but no matter how I try I just can't seem to find a way to call the function I built!
You are importing the google api value incorrectly you need to format it as
const google = require('googleapis.js');

Importing libraries using "new Function" syntax

In an API response that I'm integrating with, I receive JS code inside a JSON that I need to execute at run-time.
For that, I normally use the new Function() statement. While for most cases this works just fine, there are some other cases that contain references to external libraries such as moment or lodash.
Here's an example of such JS string:
{
...
"calculateValue": "value = moment().diff(moment(row.DateOfBirth), 'years');"
...
}
So I create a function by doing new Function('row', 'value = moment().diff(moment(row.DateOfBirth), 'years');')
and then execute it.
However, the error I'm getting is
[ReferenceError: moment is not defined]
Logically, I tried adding a reference to moment in the file where the function is being executed and also tried concatenating the import statement to the string without any luck.
Is there a way of importing external libraries using the "new Function" syntax or using "eval"?
Please bear in mind that I receive these JS strings dynamically by requesting data from a server an cannot actually write those.

parse yaml data to browser using angularjs

I have a yaml file and i want it to be read by my browser website. When I run my function in browser console, i get below error for my variable yaml
TypeError: yaml is undefined
Whereas i have declare it inside function. PFB my function
function parseyam() {
var yaml = require('js-yaml');
var fs = require('fs');
// Get document, or throw exception on error
const doc = yaml.safeLoad(fs.readFileSync('services.yml', 'utf8'));
console.log(doc);
}
I also added require.js in my index.html and tried to work around with require.js. I think the variable yaml is not working fine because of require.
Please advise, how do i make it work?
Note: When i run same code in backend, it works fine and i get data.
Is there any other way i can make it work on front end? Any other alternatives? Would be thankful if anyone could help me here.
The problem here is that NodeJS uses CommonJS module format,but the RequireJS uses AMD module format. They not compatible. There are some possible solutions to fix that, please go ahead to RequireJS site to read more: https://requirejs.org/docs/commonjs.html

Import function from sister file Node.JS

I hope to explain this in a non-abstract way. I have a problem and I believe that I am pushing the boundaries of Node because there doesn't seem to be much documentation on this particular subject.
To start out, this is my file layout.
//main.js
var 1 = require('1.js');
var 2 = require('2.js');
The purpose of this first file is to load two child files into the process.
//1.js
console.log('Test');
module.exports = function msgUSR(text){
console.log(text);
}
The purpose of this file is to create an export, this export could very obviously be imported into Main.js , however, I have a situation where I need to import a function from 1.js into 2.js without reloading the entire file into memory.
for example.
//2.js
var msgUSR = require('1.js');
msgUSR('blah');
The problem with this setup is that when you require 1.js, it reloads the entire file, including any code that isn't an export.
How could I only import the exports of a file without loading the unrelated code.
Thank you! I know someone has a solution to this.
EDIT:
I understand that the code here wouldn't replicate any useful data. My point is, how do I require a function in another JS file that is already required by a parent file. Instead of writing two long hefty functions that are exactly alike in two different files, I need to be able to call the function from a sister file.
Here is why this is an issue.
If you were to require the file after the parent has required it, 'Test' would appear two times, symbolically meaning that other complex code would also be loaded.
My hopeful result from this question would be a result where I could require the file in such a way as to only import a function from it.
Thanks again.
The problem with this setup is that when you require 1.js, it reloads
the entire file, including any code that isn't an export.
When you require something the file will be loaded once and then is cached
How could I only import the exports of a file without loading the
unrelated code?
You would never have to reload the file once it is already required since Node will use the cached version.
The require function normally has 5 steps:
Resolving: To find the path of the file
Loading: To determine the type of the file content
Wrapping: To give the file its private scope. This is what makes both the require and module objects local to every file we require.
Evaluating: This is what the VM eventually does with the loaded code.
Caching: So that when we require this file again, we don’t go over all the steps another time.

Execute NormalModule at build time, after it is built by loaders, then save to json file

I am coding a plugin that, for specific modules, will try to execute the module generated at build time in order to save the result to a json file.
For that, I am tapping into compilation.hooks.succeedModule, which receives a NormalModule object already built. Then I am trying to eval the source replacing webpack variables like __webpack_public_path__.
While it kind of works, this approach feels terribly wrong. Like I am missing something.
Is there a nice way to execute modules at build time from a NormalModule object having basic access to vars like __webpack_public_path__? Maybe Webpack offers a better way to do these kind of things?
Ok, yeah, sounds like you can solve this another way, I've done similar stuff where I needed to change what a module output, write stuff to disk, trigger side effects, etc. It sounds like you want loaders rather than a plugin. The run-loader (https://www.npmjs.com/package/webpack-run-loader) executes the module it loads and exports or returns the result.
You can write a custom loader that you chain to run after responsive-loader, and run-loader, and which receives the JSON from run-loader and writes it to disk where you want it (as a side effect), and then returns an empty string so that nothing is added to the build. The end result would be that requiring this module in your app gets your image files created (by responsive-loader), and the JSON written out to disk where you need it (by your custom loader). Alternately you could skip run-loader and in your custom loader use regex to just grab the JSON from the output of responsive-loader. Using regex on code generated by a project dependency seems fragile, but as long as you have your dependency versions locked down it can work just fine in practice, and it's a bit simpler conceptually than adding run-loader to the pipeline.
If you're writing webpack plugins I imagine you're comfortable writing loaders as well, but if not they're pretty straightforward -- just a function that accepts source code from the loader that came before it and returns code, and does whatever you want in between. The docs aren't bad for the API, but looking at the source of a few published loaders is helpful, too. It might look roughly (just spitballing from memory) like:
// img-info-logging-loader.js
// regex version, expects source arg to be output of responsive-loader
import * as fs from 'fs';
export const imgInfoLoggingLoader = (source) => {
const jsonFinderRegex = /someregexto(match)onsource/;
const desiredJSON = source;
const matchArr = jsonFinderRegex.exec(desiredJSON);
if (!matchArr[1]) {
throw new ReferenceError('json output not found in loader source.');
} else {
const imgConfigJsonString = matchArr[1];
// you would write a fn to generate a filename based on the
// source, or based on the module's filename, which is available
// via the webpack loader api
const fileNameToWrite = getFileNameTowrite();
try {
// async might be preferable depending on your webpack
// performance needs
fs.writeFileSync(fileNameToWrite, imgConfigJsonString);
} catch (err) {
throw new Error(`error writing ${fileNameToWrite}`);
}
}
// what the loader inserts into your JS asset: empty string
return '';
}
EDIT:
Since per your comment you are looking to output a single JSON object with all of the image info in it, you would want a slightly different approach that does use a plugin (this is the most elegant way I know to do it, there may be others). As far as I know a plugin is the only way to 'do something' when webpack is done loading modules.
You still want a custom loader that is extracting the JSON from the output of the responsive-loader, as described above. It won't write each to disk, though. Instead your loader will call a method on the following module:
You also write a json-collector.js that is just a little node module that you will use to hold on to the JSON object you're building. This bit is awkward because it's separate from the loader but the loader needs it. This collector module is simple, though, and if you wanted to be cleaner you could turn it into a more generic module and treat it as a proper, separate node dependency. All it is is an object with a method for adding JSON data, which appends it to an internal JSON object, and one for reading out the collected data, which returns the JSON.
And then you have a plugin that hooks into the end of the build (I think there's one for 'build sealed' that I've used). When that hook is reached, you know webpack has no more modules to load, so the plugin now calls the 'read' method on the json-collector, gets the JSON object from it and writes that to disc.
This solution doesn't fit the standalone plugin/standalone loader convention in webpack but if that doesn't bother you it's actually pretty straightforward, each of the three pieces has a simple job to do. I've used this pattern multiple times and it's worked for me.

Categories

Resources