Perl - Mojolicious Webpack Can't load application from file [closed] - perl

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
mojo webpack script\one_commex
Web application available at http://127.0.0.1:3000
Can't exec "C:\Users....\Box Sync\projects\perl_projects\mojo_projects\one_commex\node_modules.bin\webpack": No such file or directory at C:/Strawberry/perl/site/lib/Mojolicious/Plugin/Webpack/Builder.pm line 214.
Can't load application from file "C:\Users....\Box Sync\projects\perl_projects\mojo_projects\one_commex\script\one_commex": [Webpack] exec C:\Users...\Box Sync\projects\perl_projects\mojo_projects\one_commex\node_modules.bin\webpack --config C:\Users...\Box Sync\projects\perl_projects\mojo_projects\one_commex\webpack.config.js --watch: No such file or directory at C:/Strawberry/perl/site/lib/Mojolicious/Plugin/Webpack/Builder.pm line 215.
Compilation failed in require at (eval 107) line 1.
[Webpack] Could not find C:\Users...\Box Sync\projects\perl_projects\mojo_projects\one_commex\public\asset\webpack.development.html. Sure webpack has been run? at C:/Strawberry/perl/site/lib/Mojolicious/Plugin/Webpack.pm line 87.
It works in Ubuntu machine correctly.
In windows, webpack installs the packages, creates assets directory, webpack.custom.js, creates a directory in public as "asset". But, it throws the error.

I have been able to find the solution based on the trick that I learnt from setup done for my django project.
Manually created webpack.config.js for the common (development) settings and webpack.prod.config.js for the production along with package.json in the mojolicious project root directory
my webpack.config.js looks like below:
var path = require("path");
var webpack = require("webpack");
var BundleTracker = require("webpack-bundle-tracker");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
var { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
context: __dirname,
entry: './public/javascripts/index',
output: {
path: path.resolve('./public/bundles/'),
filename: "[name].js"
},
resolve: {
alias: {
'jquery': path.join(__dirname, 'node_modules/jquery/src/jquery')
}
},
plugins: [
new BundleTracker({
filename: './webpack-stats.json'
}),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
jquery: "jquery",
"window.jQuery": "jquery",
Highcharts: 'highcharts',
}),
new MiniCssExtractPlugin({
filename: `[name].css`
}),
new CleanWebpackPlugin()
],
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
},
{
test: /\.(woff(2)?|eot|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'url-loader',
}
],
},
{
test: /\.(sass|scss|css)?$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: './bundles',
}
},
{ loader: 'css-loader' },
{
loader: 'postcss-loader',
options: {
plugins: function () { // post css plugins, can be exported to postcss.config.js
return [
require('precss'),
require('autoprefixer')
];
}
}
},
{ loader: 'resolve-url-loader' },
{ loader: 'sass-loader' }
]
},
{
test: /\.(jpe?g|png|gif)$/i,
use: ['file-loader']
},
],
},
}
my layout template default.html.ep looks like this
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
%= include 'layouts/_mojo_default'
<link type="text/css" rel="stylesheet" href="/bundles/main.css">
</head>
<body>
<%= content %>
<h1 class="text-primary">All OK!<h1>
<script type="text/javascript" src="/bundles/main.js"></script>
</body>
</html>
Then, added the following scripts in my package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack.config.js --mode development",
"build-watch": "webpack --config webpack.config.js --mode development --watch",
"build-production": "webpack --config webpack.prod.config.js --mode production"
},
So, now I can open one console for running the following which takes care of building packages as and when the front-end codes change
> npm run build-watch
In other console, I run the following:
> morbo script\<app>
Before deployment, I will run the following:
> npm run build-production
And change my default.html.ep (though dynamic way can be done with the help of server side operation)
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
%= include 'layouts/_mojo_default'
<link type="text/css" rel="stylesheet" href="/dist/main.css">
</head>
<body>
<%= content %>
<h1 class="text-primary">All OK!<h1>
<script type="text/javascript" src="/dist/main.js"></script>
</body>
</html>
That's it!

Related

Using a Svelte build with a Sails node server

I am trying to set up a website with Svelte for the frontEnd and Sails for the backend.
My problem is that I can't display my Svelte public build as my Sails default web page.
I want to keep the organization below (or maybe something similar) and have my Svelte public build page when I go on 'http://myserver:1337' instead of having the default Sails page : file organization
PS: I am using Node: v14.4.0, Sails: v1.2.4 and Svelte: v6.14.5.
Thank you all :)
You could try something like:
Compile Svelt to build into the /public directory on Sails.js.
Open your rollup.config.js and change the path of your public/build/bundle.js and public/build.bundle.css to the public sails path, i.e. "../server/public...".
Configure /task/pipeline.js to include the compiled js and css files:
// tasks/pipeline.js
var cssFilesToInject = [
'css/**/global.css',
'css/**/bundle.css',
'css/**/*.css',
];
var jsFilesToInject = [
'js/**/bundle.js',
'js/**/*.js'
];
Create a controller to load the index file:
// router.js
'/*': { action: 'index', skipAssets: true, skipRegex: /^\/api\/.*$/ },
The excluded "/api" routes is to allow you to configure the CRUD routes.
The index controller:
module.exports = {
friendlyName: 'View homepage',
description: 'Display a compiled index page',
exits: {
success: {
statusCode: 200,
viewTemplatePath: 'pages/index'
},
},
fn: async function () {
return {};
}
};
And the index page you could include the template index.html or create your own index.ejs to load the static content, the same you configured before:
// views/templates/template.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Svelte app</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<!--STYLES-->
<!--STYLES END-->
</head>
<body>
<!--TEMPLATES-->
<!--TEMPLATES END-->
<%- body %>
<!-- exposeLocalsToBrowser ( ) %>
<!--SCRIPTS-->
<!--SCRIPTS END-->
</body>
</html>
And the index.ejs:
// views/pages/index.ejs
<!-- Nothing here I mean -->
Thank you for your answer it helps me to understand how does it works.
I am sorry but I did not follow your tutorial exactly (because I was not able to understand what I was supposed to do ;) ).
I edit the rollup.config.js as :
import svelte from 'rollup-plugin-svelte';
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
const production = !process.env.ROLLUP_WATCH;
const BUILD_PATH = '../server/assets';
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: `${BUILD_PATH}/build/bundle.js`
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write(`${BUILD_PATH}/build/bundle.css`);
}
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload(BUILD_PATH),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
}
}
};
}
And I move my files is the assets as :
file organization
Then I deleted the homepage.ejs in server/views/pages/
And it works :) !
Thank you again for your quick answer

How to Integrate MathJax with Ionic2

I'm getting template parsing errors while integrating MathJax into Ionic2 please help me with this,
package.json
"dependencies": {
.....
"mathjax": "^2.7.0"
},
home.ts
import mj from "mathjax";
home.html
<ion-card-title> Name </ion-card-title>
<span> When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrtb^2-4ac \over 2a.}$$</span>
<button (click)= render()> Render Katex</button>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: 'inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<script type="text/javascript" async src="../../../node_modules/mathjax/MathJax.js?config=TeX-MML-AM_CHTML"></script>
https://www.npmjs.com/package/#types/mathjax
You need to install typescript declarations.
Try
npm install #types/mathjax --save
check out this question
I have been googling "Integrating MathJax in ionic 3 offline" for last 2 days. All I found that is I have to use a directive to achieve that. But this approach is not fast for such an app which has lots of mathematical equation. So I came up with another solution:
download MathJax offline file from here, extract and rename that with MathJax and place the whole folder in www/assets folder of your ionic app.
add the code given below in the head section of index.html file
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
imageFont: null,
extensions: ["tex2jax.js"],
jax: ["input/TeX","output/HTML-CSS"],
tex2jax: {inlineMath: [["$","$"],["\\(","\\)"]]}
});
</script>
<script type="text/javascript" async
src="assets/MathJax/MathJax.js">
</script>
now for every page where you want to load mathematical equation, just paste the code below.
ionViewDidEnter() {
eval('MathJax.Hub.Queue(["Typeset", MathJax.Hub])');
}
By doing these three steps you will have integrated MathJax successfully.
But the problem is the size of MathJax folder is so big. You can reduce the size up to 3mb by just having the following directories and files
MathJax.js
extensions
fonts
HTML-CSS
TeX
eof
otf
svg
jax
element
input
TeX
output
HTML-CSS
autoload
config.js
fonts
TeX
imageFonts.js
jax.js
In your index.html file, add following script...
`
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
showProcessingMessages: false,
tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] }
});
</script>
<script type="text/javascript" async src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_HTMLorMML">
</script>
Then make a directive for mathjax as follows
import {Directive, ElementRef, Input} from '#angular/core';
declare var MathJax: {
Hub: {
Queue: (param: Object[]) => void
}}
#Directive({selector: '[MathJax]'})
export class MathJaxDirective {
#Input('MathJax') MathJaxInput: string = "";
constructor(private el: ElementRef) {
}
ngOnChanges() {
this.el.nativeElement.innerHTML = this.MathJaxInput;
MathJax.Hub.Queue(["Typeset", MathJax.Hub, this.el.nativeElement]);
}
}
Then in app.module.ts
import {MathJaxDirective} from "... to use it in you entire app
For a condition if you have multiple modules then make a commonModule something like
import { NgModule } from "#angular/core";
import { MathJaxDirective } from "./directives/MathJax.directive";
#NgModule({
declarations: [MathJaxDirective],
exports: [MathJaxDirective]
})
export class CommonModule { }
and import this module in the required module
Now you are good to go
just in your .html
<div [Mathjax]="sometxt">{{ sometxt }}</div>
and in your .ts
sometxt: string = "$$someLatex"
Hope, this will help someone

sails doesnt not auto insert dependencies with handlebars

I'm trying to use handlebars for the templating engine but sails does not seem to insert the files in the dependency folder.
/config/views.js:
engine: 'handlebars',
layout: false,
partials: false
/views/login.handlebars:
<!DOCTYPE html>
<html>
<head>
<!--STYLES-->
<!--STYLES END-->
</head>
<body>
<p>Handlebars</p>
<!--SCRIPTS-->
<!--SCRIPTS END-->
</body>
</html>
/assets/js/dependencies contains:
bootstrap.min
jquery.min
sails.io.js
When I go to the rendered page after lifting sails the files are not populated in between the scripts tag.
Thanks!!
You should update your tasks/config/sails-linker.js and replace all occurrences of ".ejs" with ".handlebars"
E.g. from:
devJs: {
options: {
startTag: '<!--SCRIPTS-->',
endTag: '<!--SCRIPTS END-->',
fileTmpl: '<script src="%s"></script>',
appRoot: '.tmp/public'
},
files: {
'.tmp/public/**/*.html': require('../pipeline').jsFilesToInject,
'views/**/*.html': require('../pipeline').jsFilesToInject,
'views/**/*.ejs': require('../pipeline').jsFilesToInject // <- HERE
}
},
to
devJs: {
options: {
startTag: '<!--SCRIPTS-->',
endTag: '<!--SCRIPTS END-->',
fileTmpl: '<script src="%s"></script>',
appRoot: '.tmp/public'
},
files: {
'.tmp/public/**/*.html': require('../pipeline').jsFilesToInject,
'views/**/*.html': require('../pipeline').jsFilesToInject,
'views/**/*.handlebars': require('../pipeline').jsFilesToInject // <-HERE
}
},
See also this page (where the original answer comes from).
https://mtjburton.co.uk/post/sailsjs+handlebarsjs/

Extending SAPUI5 Applications

I tried to acquaint myself with extending SAPUI5 Applications. To do this I used the splitapp in the folder test-resources/sap/m/demokit
As specified in the Developer Guide - Extending SAPUI5 Applications you only have to create the Component.js for a the custom application project. Now there are 2 questions:
How can you bootstrap the extended Application without having a index.html?
How do you solve relative path-problems (e.g inside the function createContent)?
My current solution is to copy the index.html from the splitapp, paste it into splittapp-ext and modify all the paths...but this solution doesn't seems to be very modular:
original index.html (splitapp):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta charset="UTF-8">
<title>'sap.m.SplitApp' Demo Application</title>
<script id='sap-ui-bootstrap' type='text/javascript'
src='../lib/openui5/resources/sap-ui-core.js'
data-sap-ui-theme='sap_bluecrystal'
data-sap-ui-libs='sap.m'
data-sap-ui-resourceroots='{
"res": "./",
"sap.ui.demo.splitapp" : "./",
"view" : "./view",
"model" : "./model",
"util" : "./util"
}' >
</script>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script>
new sap.m.Shell("Shell", {
title : "sap.m splitapp",
showLogout : false,
app : new sap.ui.core.ComponentContainer({
name : 'sap.ui.demo.splitapp'
}),
homeIcon : {
'phone' : 'img/57_iPhone_Desktop_Launch.png',
'phone#2' : 'img/114_iPhone-Retina_Web_Clip.png',
'tablet' : 'img/72_iPad_Desktop_Launch.png',
'tablet#2' : 'img/144_iPad_Retina_Web_Clip.png',
'favicon' : 'img/favicon.ico',
'precomposed': false
}
}).placeAt('content');
</script>
</head>
<body class='sapUiBody' id="content">
</body>
</html>
modified index.html (splitapp-ext):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta charset="UTF-8">
<title>'sap.m.SplitApp' Demo Application</title>
<script id='sap-ui-bootstrap' type='text/javascript'
src='../lib/openui5/resources/sap-ui-core.js'
data-sap-ui-theme='sap_bluecrystal'
data-sap-ui-libs='sap.m'
data-sap-ui-resourceroots='{
"res": "../splitapp",
"sap.ui.demo.splitapp" : "../splitapp",
"view" : "../splitapp/view",
"model" : "../splitapp/model",
"util" : "../splitapp/util"
}' >
</script>
<link rel="stylesheet" type="text/css" href="../splitapp/css/style.css">
<script>
new sap.m.Shell("Shell", {
title : "sap.m splitapp",
showLogout : false,
app : new sap.ui.core.ComponentContainer({
name : 'sap.ui.demo.splitapp'
}),
homeIcon : {
'phone' : 'img/57_iPhone_Desktop_Launch.png',
'phone#2' : 'img/114_iPhone-Retina_Web_Clip.png',
'tablet' : 'img/72_iPad_Desktop_Launch.png',
'tablet#2' : 'img/144_iPad_Retina_Web_Clip.png',
'favicon' : 'img/favicon.ico',
'precomposed': false
}
}).placeAt('content');
</script>
</head>
<body class='sapUiBody' id="content">
</body>
</html>
For the 2. question I do not have a modular solution.
The anonymous function createContent inside Component.js of the splitapp defines a relative path to the JSON-models. The models cant't be found inside the splitapp-ext Application. The only way I found is to modify the Component.js:
createContent : function () {
// create root view
var oView = sap.ui.view({
id : "app",
viewName : "view.App",
type : "JS",
viewData : { component : this }
});
// --> WORKAROUND: add the module path to the JSON-paths
var rootPath = jQuery.sap.getModulePath("sap.ui.demo.splitapp");
// set navigation model
// load the global data model
var oJSONDataModel = new sap.ui.model.json.JSONModel(rootPath + "/model/data.json");
oView.setModel(oJSONDataModel);
// load the global image source model
var oImgModel = new sap.ui.model.json.JSONModel(rootPath + "/model/img.json");
oView.setModel(oImgModel, "img");
// done
return oView;
}
Is there a better way to extend a SAPUI5 Application?
You can try the extension of an app using SAP Web IDE . You can find the trial links on SAP SCN . The whole idea of Component based approach is to enable the applications to be launched in a broader context such as a Fiori Launchpad . If you want to test it locally, you might consider setting up a local launchpad sandbo from this link:
Set up local Fiori Launchpad.
It is possible to run a local test version of launchpad (with limitations).
first three search results
detailed wiki
As for the second question, remember that control is looking for a model matching the bind path inside on itself, later on parents, and bubbling up to the core. So, setting a model to one view is not best option. You can set model directly to the Component.js as whole application have access there, or just for testing, to the core - sap.ui.getCore().setModel(myModel).
This is an example from ui documentation of proper definition of Component.js with assigned models (for version 1.30, for previous ones you probably won't use 'define'):
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel",
"sap/ui/model/resource/ResourceModel"
], function (UIComponent, JSONModel, ResourceModel) {
"use strict";
return UIComponent.extend("sap.ui.demo.wt.Component", {
metadata : {
manifest: "json"
},
init : function () {
// call the init function of the parent
UIComponent.prototype.init.apply(this, arguments);
// set data model
var oData = {
recipient : {
name : "World"
}
};
var oModel = new JSONModel(oData);
this.setModel(oModel);
// set i18n model
var i18nModel = new ResourceModel({
bundleName : "sap.ui.demo.wt.i18n.i18n"
});
this.setModel(i18nModel, "i18n");
}
});
});
Similar sample documented in openui5 you can find here:
component and model sample

RequireJS optimizer fails to load external facebook js correctly

My file structure looks like this. Everything is inside the js folder.
-js
--config.js
-app
--app.fb.js
--main.js
-lib
--jquery-1.9.0.js
--require.js
-tools
--r.js
--build.js
I've created a config file as per https://developers.facebook.com/docs/javascript/howto/requirejs
config.js
require.config({
shim: {
'facebook' : { exports: 'FB' }
},
paths: {
'jquery': '../lib/jquery-1.9.0',
'facebook': '//connect.facebook.net/en_US/all'
}
});
app.fb.js
define(['facebook'], function(){
console.log("loaded fb");
});
build.js
({
baseUrl: "../app",
mainConfigFile: "../config.js",
name: "main",
out: "../core.js",
paths: {
'facebook': 'empty:'
}
})
main.js
require(["jquery", "app.fb"], function($, appfb){
// Log the callback parameter.
console.log( "$.fn.jquery:", $.fn.jquery );
});
finally I call the optimized file(core.js) here
<script type="text/javascript" data-main="js/core" src="js/lib/require-2.1.15.js"></script>
The optimizer appears to run correctly but when I load the page I expect the Facebook module to load in from the CDN. Instead I get
GET http://example.com/js/facebook.js require-2.1.15.js:1901
Uncaught Error: Script error for: facebook
I've spent ages on this and can't figure out the problem!
Any thoughts?
Thanks
Got it, for some reason this only worked when I moved the config.js contents into main.js.
This looks like:
require.config({
shim: {
'facebook' : { exports: 'FB' }
},
paths: {
'jquery': '../lib/jquery-1.9.0',
'facebook': '//connect.facebook.net/en_US/all'
}
});
require(["jquery", "app.fb"], function($, appfb){
// Log the callback parameter.
console.log( "$.fn.jquery:", $.fn.jquery );
});
In build.js, change
mainConfigFile: "../app/config.js",
to
mainConfigFile: "../app/main.js",
r.js optimiser runs correctly!