Javascript dependency in PHP library - javascript

I have a PHP library that depends on a Javascript repo (also my lib). In the PHP lib, I don't want a CDN url or a minified copy. The PHP lib uses a framework (also home-brewed) that will compile the JS files together along with all the resources on my site.
I don't want to change anything about the JS lib, aka I don't want to make a composer.json file. I'm aware git submodule exists, though I'm not sure how to use it and I've read that it's a thoroughly bad way to handle dependencies, and I'm guessing my submodules wouldn't get included through composer?
Are there any other ways to include a JS dependency in a PHP library? (aside from copy+pasting the files) (and/or tips to make submodule a good option)

Composer defaults to using the metadata from Packagist, which Packagist pulls from each repo's composer.json file.
However, it is possible to just specify any file that you want to download yourself. It might be a bit cumbersome if you want to have a lot of versions though.
Composer has some documentation about it here but I tried it out myself and will include my sample composer file below. I was able to use composer update to download a git repo which didn't contain a composer.json file.
Sample Composer file for the PHP project:
It looks like you'll need a "package" section for each version you want.
{
"repositories": [
{
"type": "package",
"package": {
"name": "testy/testyson",
"version": "1.0.0",
"dist": {
"url": "https://github.com/mickadoo/testlib/archive/1.0.0.zip",
"type": "zip"
}
}
},
{
"type": "package",
"package": {
"name": "testy/testyson",
"version": "2.0.0",
"dist": {
"url": "https://github.com/mickadoo/testlib/archive/2.0.0.zip",
"type": "zip"
}
}
}
],
"require": {
"testy/testyson": "2.*"
}
}
The test repository I loaded just contains a text file with the contents "This is version 1" and using the different version in the require section of the PHP package I was able to switch between them.

Related

How to create an express api executable

I have created a fully functioning fairly basic javaScript Node.js Express API application that I want to run as an executable in a windows environment. I am wanting to do this so I can give clients the ability to run my API on premise without exposing my source code to them.
Currently I have been using the pkg npm package which allows me to package my node.js application into an executable that will contain everything needed to run the app including node and my bundled source code.
My executable runs but my POST route is breaking with the following error:
"name": "RequestError",
"message": "Error: form-data: File or directory 'C:\\**\\myapp-api\\uploads\\1553103249524_test.wav' was not included into executable at compilation stage. Please recompile adding it as asset or script.",
"cause": {
"errno": -4058,
"code": "ENOENT",
"path": "C:\\snapshot\\myapp-api\\uploads\\test.wav",
"pkg": true
},
"error": {
"errno": -4058,
"code": "ENOENT",
"path": "C:\\snapshot\\myapp-api\\uploads\\1553103249524_test.wav",
"pkg": true
},
My POST allows clients to upload a file in a multipart form using multer.js to another external API that will return some metadata. pkg.js doesn't appear to have the means to discover files that are included after the bundling of the executable.
Is there anything I can do in my configuration for my uploaded files to be included? Is there some other utility or process that others use for creating an executable of their node.js express APIs that would better handle the issue I am having?
Any guidance would really be great.
Try adding your files under "assets" in the package.json file.
The config paragraph on the pkg website https://www.npmjs.com/package/pkg#config states:
So you must specify the files - scripts and assets - manually in pkg property of your package.json file.
"pkg": {
"scripts": "build/**/*.js",
"assets": "views/**/*"
}
You may also specify arrays of globs:
"assets": [ "assets/**/*", "images/**/*" ]
Just be sure to call pkg package.json or pkg . to make use of scripts and assets entries.
You are probably using something like this in your script (I am guessing since you didnt provide this part of the code)
app.use(express.static(__dirname+'/uploads'));
res.sendFile(path.join(__dirname+'/uploads'));
__dirname will be wrong when you pack your .exe get rid of it everywhere and replace it with ./
app.use(express.static('./uploads'));
res.sendFile(path.join('./uploads'));
Something like that. It worked for me.
Good luck!

Angular Cli Webpack, How to add or bundle external js files?

I am not sure how to include JS files (vendors) after switching Angular Cli from SystemJs to Webpack.
For example
Option A
I have some js files that were installed via npm. Adding script tags to the head tag like this does not work. Nor does it seem like the best way.
<head>
<script src="node_modules/some_package/somejs.js">
</head>
//With systemJs I could do this
<head>
<script src="vendor/some_package/somejs.js">
</head>
Option B
Include these js files as part of the webpack bundle. This seems like the way it probably should be done. However I am not sure how to do this as all of the webpack code seems to be hidden behind the angular-cli-webpack node package. I was thinking maybe there is another webpack config that we might have access to. But I am not sure as I didn't see one when creating a new angular-cli-webpack project.
More Info:
The js files I am trying to include need to be included before the Angular project. For example jQuery and a third party js lib that isn't really setup for module loading or typescript.
References
https://github.com/angular/angular-cli/blob/master/WEBPACK_UPDATE.md
https://github.com/angular/angular-cli/tree/webpack
Last tested using angular-cli 11.x.x with Angular 11.x.x
This can be accomplished using scripts:[] in angular.json.
{
"project": {
"version": "1.0.0",
"name": "my-project"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": ["assets"],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.json",
"prefix": "app",
"mobile": false,
"styles": [
"styles.css"
],
"scripts": [
"../node_modules/jquery/dist/jquery.js"
],
"environments": {
"source": "environments/environment.ts",
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"addons": [],
"packages": [],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"prefixInterfaces": false
}
}
Note: As the documentation suggests in the global library installation: if you change the value of your styles (or scripts!) property, then:
Restart ng serve if you're running it,
..to see the scripts executed in a **globalcontext via the scripts.bundle.js file.
Note: As discussed in the comments below. JS libs that support UMD modules via es6 imports such as jQuery can also be imported into your typescript files using the es6 import syntax. For example: import $ from 'jquery';.
There is a subtle difference to using scripts:[] then to adding something to the <head> with <script>. Scripts from scripts:[] get added to the scripts.bundle.js that gets always loaded in the body tag and will thus be loaded AFTER scripts in <head>. Thus if script loading order matters (i.e. you need to load a global polyfill), then your only option is to manually copy scripts to a folder (e.g. with a npm script) and add this folder as an asset to .angular-cli.json.
So if you really depend on something being loaded before angular itself (Option A), then you need to copy it manually to a folder that will be included in the angular build and then you can load it manually with a <script> in <head>.
Thus, for achieving option a you have to:
create a vendor folder in src/
add this folder as an asset to .angular-cli.json:
"assets": [
"assets",
"favicon.ico",
"vendor"
]
copy your vendor script node_modules/some_package/somejs.js to vendor
load it manually in index.html:
<head>
<script src="vendor/some_package/somejs.js">
</head>
However most of the time you only need this approach for packages, that need to be available globally, before everything else (i.e. certain polyfills). Kris' answer holds true for Option B and you get the benefit of the webpack build (Minification, Hashes, ...).
However if your scripts need not be globally available and if they are module-ready you can import them in src/polyfills.ts or even better import them only when you need them in your specific components.
Making scripts globally available via scripts:[] or via manually loading them brings it own set of problems and should really only be used, when it is absolutely necessary.
You need to open file .angular-cli.json file and need to search for
"scripts:" or if you want to add external css you need to find the word "styles": in the same file.
as an example shown below you will see how the bootstrap Js(bootstrap.min.js) and bootstrap CSS(bootstrap.min.css) includes in .angular-cli.json:
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/bootstrap/dist/js/bootstrap.min.js"
],
For sure if you have your own js file you can add your file path here in .angular-cli.json at the same place(in "scripts":[]).
You might want to have a look at this page:
https://github.com/angular/angular-cli#global-library-installation
It show the basics of how to include .js and .css files
Some javascript libraries need to be added to the global scope, and loaded as if they were in a script tag. We can do this using the apps[0].scripts and apps[0].styles properties of angular-cli.json.
I havn't used angular-cli before but I'm currently working with an Angular/Webpack build. In order to provide my application with jQuery and other vendors I use webpack's plugin, ProvidePlugin(). This will typically sit in your webpack.config.js: Here's an example for jquery, lodash and moment libraries. Here's a link to the documentation (which is vague at best)
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
_: 'lodash',
moment: 'moment',
})
]
Incredibly, it actually allows you to use it right away, providing all other webpack setup has been done correctly and have been installed with npm.

Should vendor assets be included in version control with bower + rails?

I've started to use bower-rails to manage css/js assets in my rails projects.
By default the dependences are being installed in vendor/assets/bower_components.
The problem is that bower copies the whole packages, including sources, examples, licenses, etc.
I don't have problem to get rid of all those files, but I'm wondering if is necessary to include even the important files, as I think it should be the programmer's responsibility to load those dependences in the computer where is loading the project(maybe with grunt?), besides is supposed you should not touch the vendor packages as they are not your responsibility(regarding all those crappy files I want to delete).
My point is: Is there any kind of "best practice" related with bower packages and version control?
I recently used bower-rails for the first time and had Git ignore the vendor/assets/bower_components directory to good effect.
If you choose to have Git ignore bower_assets, you SHOULD specify a known good version of each library in bower.json instead of using latest to avoid version conflicts.
I'm using bower and bower-installer in my Rails 4.2.x app, without using any gems for javascript dependencies. I'm still using the asset pipeline.
I added vendor/assets/bower_components to my .gitignore file. I use bower-installer to copy just what I need to vendor/assets/{javascripts,stylesheets}, which are in source control.
I think that this gives me the best of both worlds: version control of JS libraries so updates are relatively easy, but no chance of a production deploy failing because someone removed 'leftpad' from the node repo.
Here's a trimmed-down version of my bower.json file (in source control). Note that jquery-form is not in the bower repo, so I included the path to the download file.
{
"name": "icots",
"main": "",
"private": true,
"ignore": [
"**/.*",
"bower_components",
"vendor/assets/bower_components",
"lib"
],
"dependencies": {
"jquery": "^3.1.1",
"jquery-ui": "^1.12.1",
"jquery.form": "http://malsup.github.io/min/jquery.form.min.js"
},
"install": {
"path": {
"js": "vendor/assets/javascripts",
"css": "vendor/assets/stylesheets",
"/[sc|le]ss$/": "vendor/assets/stylesheets"
},
"sources": {
"jquery": "vendor/assets/bower_components/jquery/dist/jquery.min.js",
"jquery-ui": "vendor/assets/bower_components/jquery-ui/jquery-ui.min.js",
"jquery-form": "vendor/assets/bower_components/jquery.form/index.js"
}
}
}

How to deploy client side dependencies on webserver?

I have done some web developing using Python and Django. I use virtualenv to make a bootstrap script that can install all my Python dependencies on a server. I have a repository for the code I have written myself, and in that repository are two file (beside my code): requirements.txt and bootstrap.py. Using the bootstrap script, it installs all the dependencies on the server.
Now I would like something similar for the client side dependencies. E.g. jQuery, jQuery-ui and bootstrap. Currently I manually download the files and put them in the static folder on the server.
I have run into Bower, and I understand that it can indeed download various js-libraries. But I don't see how to use it in an elegant way. E.g. for jQuery it downloads the entire jQuery repository, which means both a dist folder and a src folder, containing tons of files. All I need is the jQuery.min.js.
Well, wide question, what is the neat way of automating the deployment of client side dependencies?
you can use composer
{
"require": {
"jquery/jquery": "*"
},
"repositories": [
{
"type": "package",
"package": {
"name": "jquery/jquery",
"version": "1.8.2",
"dist": {
"url": "http://code.jquery.com/jquery-1.8.2.min.js",
"type": "file"
}
}
}
]
}

Add a javascript library to angular-brunch-seed

I clone angular-bunch-seed on my computer
https://github.com/scotch/angular-brunch-seed
And I want to add breezejs to my project
http://learn.breezejs.com/
I copied the breeze libraries into my vendor folder /vendor/breeze/
And then I changed the config.coffee file as follow:
exports.config =
# See docs at http://brunch.readthedocs.org/en/latest/config.html.
conventions:
ignored: /(^vendor\/.*\.less$)|(^|\/)node_modules\/|(^|\/)_/
assets: /^app\/assets\//
modules:
definition: false
wrapper: false
paths:
public: '_public'
files:
javascripts:
joinTo:
'js/app.js': /^app/
'js/vendor.js': /^vendor/
'test/scenarios.js': /^test(\/|\\)e2e/
order:
before: [
'vendor/console-polyfill/index.js'
'vendor/jquery/jquery.js'
'vendor/breeze/breeze.debug.js'
'vendor/breeze/q.js'
'vendor/angular/angular.js'
'vendor/angular-resource/angular-resource.js'
'vendor/angular-cookies/angular-cookies.js'
'vendor/angular-sanitize/angular-sanitize.js'
'vendor/bootstrap/docs/assets/js/bootstrap.js'
]
stylesheets:
joinTo:
'css/app.css': /^(app|vendor)/
order:
before: [
'app/styles/app.less'
]
templates:
joinTo:
'js/dontUseMe' : /^app/ # dirty hack for Jade compiling.
plugins:
jade:
pretty: yes # Adds pretty-indentation whitespaces to output (false by default)
jade_angular:
modules_folder: 'partials'
locals: {}
bower:
extend:
"bootstrap" : 'vendor/bootstrap/docs/assets/js/bootstrap.js'
"angular-mocks": []
"styles": []
asserts:
"img" : /bootstrap(\\|\/)img/
"font": /font-awesome(\\|\/)font/
# Enable or disable minifying of result js / css files.
# minify: true
And when i execute brunch build, check the vendor.js file.. no breeze library included!
What am i missing?
PS: When I remove angular.js from the build file, it's properly removed.
Well, the answer has easy and complex subparts.
The easy part: why it does not work.
angular-brunch-seed makes use of the bower-brunch package, which internally checks for component.json files in the vendor libraries.
That means that if you did not download the library using bower, or place the required component.json at the library's root (and a mention in the root component.json), it will not be recognized as a proper vendor library and get ignored in the config.coffee's joinTo regular expression.
The order part of this config.coffee file only manages the order of placement of your libraries in the generated vendor.js file; if that library gets ignored beforehand, the order line has no influence.
Tricky part: get breeze into your vendor libraries.
The clean way should be to download it using bower. Thing is, there is as of today no bower package for breeze, as you might have guessed.
[victor#M]<~> bower search breeze
No results
[victor#M]<~> bower search | \grep breeze
No results
That means that you'll have to create it yourself. As explained in the bower docs, you'll have to package the bower final library files (not the sources) and a component.json in a git endpoint (github for instance) under some name (say, bower-breeze) and register it to bower using bower register. Take a look at what angular guys did, for inspiration.
You will also have to include semver tags in that repository to match the versions of the base library.
Alternatively, you could open an issue on breeze's github and ask for a component.json to be included in their repository (or better yet, write it and file a pull request).
Last measure, you may try to just write the component.json in your vendor directory and check if it still gets ignored, but I did not test that. Could work (but it's a hack) Maybe you would have to at least add a mention of it in angular-brunch-seed's root component.json too (with version info)
To sum up, angular-brunch-seed is a tricky beast...
I followed your recommendations and sent a pull request to the Breeze team.
After the pull request has been accepted, I will had the repo to bower if not done by them already.
for now I created a component.json file into my ./vendor/breeze folder
{
"name": "breeze",
"version": "1.2.9",
"main": "./breeze.debug.js",
"dependencies": {},
"gitHead": "0b0891a13d0023bbfdf91785bd99ac5a416bf9c7",
"_id": "BreezeS#1.2.9",
"readme": "ERROR: No README.md file found!",
"description": "ERROR: No README.md file found!",
"repository": {
"type": "git",
"url": "git://github.com/IdeaBlade/Breeze.git"
}
}
the gitHead is random.. but whatever, when I run brunch build, I can finally see breeze included into vendor.js !
Thx a lot

Categories

Resources