Replace image links in json file to base64 encoded data using webpack - json

I have to create easily configurable website bundled into single file.
I'm using webpack 4.x
I have created json file with "configuration"
{
"externals": [
{ "link": "http://lynda.com", "image": "./assets/lynda.jpg" },
{ "link": "https://www.mindtools.com/community", "image": "./assets/mindtools.jpg" },
{ "link": "https://www.ted.com/talks", "image": "./assets/ted.jpg" },
{ "link": "https://stackoverflow.com", "image": "./assets/stack.jpg" }
]
}
I have also configured base64-inline-loader in webpack
// {
// test: /\.(jpg|jpeg|png)(\?.*)?$/,
// use: 'base64-inline-loader?name=[name].[ext]'
// },
{
test: /\.(jpg|jpeg|png)(\?.*)?$/,
loader: 'base64-inline-loader',
options: {
name: utils.assetsPath('[name].[ext]')
}
},
Both configurations above didn't work.
URLs created in vue component based on json data are still relative to file and of course those links points to 404 URLs.
All other inline images for CSS and HTML are processed correctly.
I'm doing something wrong, but i don't know what is this.
Any ideas?

Done, but i'm not 100% happy with this resolution.
I have moved all data from json to application controller with require clause
data() {
return {
externals: [
{ link: "https://lynda.com", image: require('./assets/lynda.jpg') },
{ link: "https://www.mindtools.com/community", image: require('./assets/mindtools.jpg') },
{ link: "https://www.ted.com/talks", image: require('./assets/ted.jpg') },
{ link: "https://stackoverflow.com", image: require('./assets/stack.jpg') }
]
};
}
on webpack site i'm using classic url-loader
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
// limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
still looking for normal json file processing possibility

Related

Why am I receiving the error 'Field browser doesn't contain a valid alias configuration' when starting via the terminal using Webpack to compile SCSS?

It's my first time using webpack to compile my scss. I'm trying to start it but I get an error. It says:
Field 'browser' doesn't contain a valid alias configuration
And also:
Module not Found: Error: Can't resolve './src'
Furthermore, in red, it'll log my file directory with /index doesn't exist (.js / .json / .wasm). This is my current webpack.config.js file:
module.exports = [{
entry: 'mat-design.scss',
output: {
filename: 'style-bundle.js',
},
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'file-loader',
options: {
name: 'styles.scss',
},
},
{ loader: 'extract-loader' },
{ loader: 'css-loader' },
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
mode: development,
webpackImporter: false,
},
},
]
}
]
},
}];
Any help would be much appreciated.
Looks like you are missing the resolve module to inform webpack what file type to look for when you have a file name without an extension
Add the following block to your configuration
module.exports = [{
entry: 'mat-design.scss',
(...)
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.css', '.scss'],
modules: ['src', 'node_modules'] // Assuming that your files are inside the src dir
}
}]
Ref - https://webpack.js.org/configuration/resolve/

How to render a JSON template using mustache

I'm trying to generate a JSON file with mustache with the following template:
{
"name": "{{customer_info.first_name}}",
"email": "{{contact_info.email}}",
"campaign": {
"campaignId": "{{contact_info.campaign.campaignId}}"
},
"tags": [
{{#contact_info.tags}}
{
"tagId": "{{tagId}}"
},
{{/contact_info.tags}}
]
}
As an output example I get:
{
"name": "Antonio",
"email": "myemail#gmail.com",
"campaign": {
"campaignId": "pfft"
},
"tags": [
{
"tagId": "6prrtAP"
},
{
"tagId": "64rrrE9"
},
]
}
Which unluckily is a BAD FORMATTED JSON, because there is a not wanted "," after the last element in the array.
Can any of you help me in solving this issue and remove the comma ?
Thanks a lot
Try using SelectTransform npm package. It has Mustache like syntax without all the side-effects that Mustache creates and the package size is also not as heavy as Handlebars.js
import ST from "stjs";
const data = {
name: 'Jakub',
friends: [
{
name: 'Michal'
}
]
};
const template = {
newName: '{{ name }}',
friends: {
'{{ #each friends }}': {
subName: '{{ name }}'
}
}
};
console.log(ST.select(data).transformWith(template).root());
// Result:
/**
* {
* "newName": "Jakub",
* "friends": [
* {
* "subName": "Michal"
* }
* ]
* }
*/
I would do this:
var md = {};
var tagsCount = 2;
var currTagIndex = 0;
md['show_comma'] = function(){
currTagIndex++;
return currTagIndex <= tagsCount;
}
Then in Mustache template:
{{#show_comma}}
,
{{/show_comma}}
I've been experiencing some similar problem and I found out that Handlebars is a lot similar to mustache and way more powerful.
You could check that out and try using this template to solve your problem, without adding anything to your current model.
{
"name": "{{customer_info.first_name}}",
"email": "{{contact_info.email}}",
"campaign": {
"campaignId": "{{contact_info.campaign.campaignId}}"
},
"tags": [
{{#each contact_info.tags}}
{
"tagId": "{{tagId}}"
}{{#unless #last}},{{/unless}}
{{/each}}
]
}
Don't generate JSON from textual templates. You'll constantly face problems like this. Superfluous commas, meta characters in strings (what if customer_info.first_name contains double quotes), failing to properly nest structures etc.
Generate your data as native structures in your programming language, and encode it as JSON using library provided by your programming language.
However, if you absolutely need, try to generate as much JSON data as possible (ideally, self-contained JSON fragment) outside template, and interpolate that inside template. For example:
let contact_info = {"tags": [ "6prrtAP", "64rrrE9" ]}
let tags = contact_info.tags.map((tag) => ({"tagId": tag})); // [{tagId: "6prrtAP"}, {tagId: "64rrrE9"}]
let tagsJSON = JSON.stringify(tags); // "[{\"tagId\":\"6prrtAP\"},{\"tagId\":\"64rrrE9\"}]"
Then, pass tagsJSON to your template:
{
"name": "{{customer_info.first_name}}",
"email": "{{contact_info.email}}",
"campaign": {
"campaignId": "{{contact_info.campaign.campaignId}}"
},
"tags": {{tagsJSON}}
}
That way, tagsJSON always contains valid JSON-encoded data, so it might be safely interpolated as a value in JSON dictionary/object. Even if tag list is empty, even if tag IDs suddenly start to contain characters that need escaping etc. All corner cases are already handled for you.
This looks like a good answer:
contact_info['tags'][ contact_info['tags'].length - 1 ].last = true;
and the template would be
{{#contact_info.tags}}
{
"tagId": "{{tagId}}"
} {{^last}}, {{/last}}
{{/contact_info.tags}}
Source: https://stackoverflow.com/a/7591866

json-server - Using nested request

I just start using json-server and struggling with one thing. I want to have URL which are nested so e.g. to get user orgs, request would looks like:
/rest/user/orgs and will return array of user orgs
{
"rest": {
"user": {
"select": {
"org": []
},
"orgs": [{
"id": "5601e1c0-317c-4af8-9731-a1863f677e85",
"name": "DummyOrg"
}],
"logout": {}
}
}
}
Any idea what I am doing wrong?
This is not supported by the library. The way to get this working is to add a custom routes file to de server, where you will map (or redirect) requests made to /rest/user/ to /.
db.json
{
"select": {
"org": []
},
"orgs": [{
"id": "5601e1c0-317c-4af8-9731-a1863f677e85",
"name": "DummyOrg"
}],
"logout": {}
}
routes.json
{
"/rest/user/*": "/$1"
}
and then run it using json-server db.json --routes routes.json

Module parse failed when using Riot with Webpack, and Babel for es2015

I have a project that is using ES2015 for the code, and also using Riot.
(The Riot components, however, do not need to be in ES2015, just old JS)
I am also using Webpack to build the project.
The problem I am getting is :
"ERROR in ./src/test-tag.tag
Module parse failed:
.../tag-loader/index.js!.../riotjs-loader/index.js?{"type":"none"}!.../test-tag.tag
Unexpected token (5:18) You may need an appropriate loader to handle
this file type."
It is complaining because of the way riot component script code looks, ie. a function must have just this for it's declaration functionName() { /* the code */ } , ie. there is no keyword function.
Here is my full project
app.js
import 'riot';
import 'test-tag.tag';
riot.mount("*");
test-tag.tag
<test-tag>
<h1>This is my test tag</h1>
<button onclick{ click_action }>Click Me</button>
<script>
//click_action() { alert('clicked!'); }
</script>
</test-tag>
index.html
<html>
<head></head>
<body>
<test-tag></test-tag>
<script src="app_bundle.js"></script>
</body>
</html>
package.json
{
"name": "riot_and_webpack",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel": "^6.5.2",
"babel-core": "^6.11.4",
"babel-loader": "^6.2.4",
"babel-preset-es2015-riot": "^1.1.0",
"riot": "^2.5.0",
"riotjs-loader": "^3.0.0",
"tag": "^0.3.0",
"tag-loader": "^0.3.0",
"webpack": "^1.13.1",
"webpack-dev-server": "^1.14.1"
}
}
webpack.config.js
var webpack = require('webpack');
const path = require('path');
const PATHS = {
src: path.join(__dirname + '/src'),
dist: path.join(__dirname + '/build'),
};
module.exports = {
entry: [path.join(PATHS.src, '/app.js')],
resolve: {
modulesDirectories: ['node_modules', '.'],
extension: [ '.js' ]
},
output: {
path: PATHS.dist,
filename: 'app_bundle.js'
},
plugins: [
new webpack.ProvidePlugin({
riot: 'riot'
})
],
module: {
preLoaders: [
{ test: /\.tag$/, exclude: /node_modules/, loader: 'riotjs-loader', query: { type: 'none' } }
],
loaders: [
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: 'babel',
query: {
presets: ['es2015']
}
},
{ test: /\.tag$/, loader: 'tag' },
]
}
};
Now - that will all work as expected, except that clicking the button does nothing because that code is commented out.
If the click_action line in test-tag.tag is uncommented, then $ webpack results in the error quoted at the top of this (horribly huge) question.
Is there any way I can get webpack to accept the standard riot code?
OR
Is there a different way I can define riot internal functions in a way that webpack will not complain about?
Have in mind that the "ES6 like" method syntax is something added by Riot, is not standard ES6.
This will be the standard js syntax
this.click_action = function() {
alert('clicked!')
}
And this the es6 syntax
this.click_action = () => {
alert('clicked!')
}
Also you have a typo in your button definition, it will be like this
<button onclick={click_action}>Click Me</button>

How to load multidimensional / nested json into a store?

So I'm trying to load the data received from a webservice into a sencha touch 2 store.
The data is nested JSON, however it is made to include multiple dataArrays.
I am working with sencha touch 2.3.1, somewhat equal to Ext JS 4.2. I don't have that much experience with sencha yet, but I'm getting there. I decided to go for MVC, so I'd like the answers to be as close to this as possible :).
This is the example JSON I am using:
[
{
"DataCollection": {
"DataArrayOne": [
{
"Name": "John Smith",
"Age": "19"
},
{
"Name": "Bart Smith",
"Age": "16"
}
],
"DataArrayTwo": [
{
"Date": "20110601",
"Product": "Apple",
"Descr": "",
"Remark": ""
},
{
"Date": "20110601",
"Product": "Orange",
"Descr": "",
"Remark": ""
},
{
"Date": "20110601",
"Product": "Pear",
"Descr": "",
"Remark": ""
}
],
"DataArrayThree": [
{
"SomeTotalCost": "400,50",
"IntrestPercentage": "3"
}
]
}
}
]
Through only one call, I get this json. I don't want to cause any unnecessary traffic so I hope to be able to use the data somehow.
I want to be able to use each DataArray on its own.
The data gets sent to the store through its proxy:
Ext.define("MyApp.store.myDataObjects", {
extend: "Ext.data.Store",
config: {
model: "MyApp.model.myDataObject",
proxy: {
reader: {
type: "json",
rootProperty: "DataCollection"
},
type: "ajax",
api: {
read: "https://localhost/Service.svc/json"
},
limitParam: false,
startParam: false,
pageParam: false,
extraParams: {
id: "",
token: "",
filter: ""
},
writer: {
encodeRequest: true,
type: "json"
}
}
}
});
I am a bit stuck with the model here. I tried using mappings which would look like this:
config: {
fields: [ {
name: "IntrestPercentage",
mapping: "Calculation.IntrestPercentage",
type: "string"
}
]}
I tried associations as well but to no avail.
According to google chrome console, it doesn't make any objects containing data. I get only 1 object with all values "null".
My endgoal is to be able to show each dataArray in a separate table. So a table for DataArrayOne, a table for DatarrayTwo... The data itself isn't linked. They are only details that have to be shown on a view.
John Smith isn't related to the apples, as in he didn't buy. The apples are just there as an item to be shown.
The possible solutions I've seen yet not understood due to them being outdated are:
ChildStores: You have a master store that receives the data, and then
you split the data to other stores according to rootProperty. I have
no idea how to do this however and I'm not sure if it will work at
all.
Associations, in case I was doing them wrong. I don't think they
are needed because the data isn't linked to each other but it is part
of "DataCollection" though.
Could someone please post an example on how to deal with this unusual(?) kind of nested json.
Or any other solution which will lead to being able to use the 3 dataArrays at will.
Thanks in advance
The best would be to load the complete data with a separate Ext.Ajax.request and then use store.loadData in the success callback. For example:
var data = Ext.decode(response.responseText);
store1.loadData(data[0].DataCollection.DataArrayOne);
store2.loadData(data[0].DataCollection.DataArrayTwo);
store3.loadData(data[0].DataCollection.DataArrayThree);