Laravel, Datatable, Composer and Webpack : Good practices to allow developpers to customize my library in their projects - laravel

To set the context I am creating a CRUD application for Laravel. It is installed via composer and the sources are therefore in the vendor/organization/package directory.
In my project, I use Datatable. So I use Laravel Mix to compile my sources and a command line allows to copy JS and CSS compiled files into the public directory of the Laravel Host application.
I would like however that the developers who will use my library can customize the display of some Datatable cells. To do this you must use Datatable's createdCell configuration.
$('#example').dataTable( {
"columnDefs": [ {
"targets": 3,
"createdCell": function (td, cellData, rowData, row, col) {
if ( cellData < 1 ) {
$(td).css('color', 'red')
}
}
} ]
});
The problem is that the JS sources of my project are already compiled...
For the moment I found a temporary solution that consists in leaving the JS sources in vendor/organization/package but copying the webpack.mix.js configuration into the Host application and asking the developers to compile themselves. The problem is that all JS dependencies must also be installed and it doesn't take very seriously to force the developers to compile sources before being able to use my library.
What are good practices to achieve this objective?
The following source may help, but I confess I don't know how to apply it to Laravel:
How to bundle vendor scripts separately and require them as needed with Webpack?
Thank you for your help.

Related

WebPack in VS2015: How to configure a new pack?

I've started with a template from this extension to have a running angular2+ .net core starting point. I didn't want to use boostrap, but materialize-css, so I removed the bootstrap package in package.json, instead I added "materialize-css": "0.98.0",
Then I edited the webpack.config.vendor.js, I removed bootstrap and added materialize-css to the "vendor" list.
Then I rebuilt everything, but it seems that materialize-css is still not present(cannot find its css classes). I tried to clear the browser cache, tried even to open on a brand new browser(edge), but still, no materialize-css classes.
What did I miss?
EDIT
Currently, my vendor list is the following:
vendor: [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router',
'#angular/platform-server',
'angular2-universal',
'angular2-universal-polyfills',
'materialize-css',
'es6-shim',
'es6-promise',
'jquery',
'zone.js',
]
You're doing everything correctly, just need to do one thing slightly differently. In your webpack.config.vendor.js, instead of materialize-css, add materialize-css/dist/css/materialize.css to the vendor array:
...
entry: {
vendor: {
...
'materialize-css/dist/css/materialize.css',
...
}
}
This will include the css to your resulting bundle. If you also need fonts and js from materialize-css, you'll need to configure appropriate loaders, see https://www.npmjs.com/package/materialize-loader

Vuejs 2 + laravel elixir + lodash Uncaught ReferenceError: _ is not defined

I'm using the tools specified in the title. I import lodash in my bootstrap.js
window._ = require('lodash');
However, when I try to use something like this (similar example to here), I get the error discribed in the title
created() {
this.test();
},
methods: {
test: _.debounce(function () {
console.log('calculating', true);
setTimeout(function () {
console.log('calculating', false);
}.bind(this), 1000)
}, 500),
}
However, if I remove the window._ = require('lodash'); and insert lodash manually in the page it works fine, like
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.js"></script>
What I'm missing?
Also, What is the advantage of importing the libraries by require instead of using Gulp to merge and uglyfy everything?
I am not sure why you are getting that error related to _.
On your other question, I can think following advantage of using require over gulp or any other build tool:
All build tools comes with their own set of dependencies and other accessories, which bloats your overall code size.
You may start to rely on their plugins and time can come, when you need to use grunt for one task, while for other tasks you are using grunt, quting from gulp-grunt
What if your favorite grunt plugin isn't available for gulp yet? Don't fret, there is nothing to worry about! Why don't you just hook in your grunt configuration?
You will have to manage updating of different plugins of gulp and make sure all are working with new updated versions.
These are some of the things I have experienced or read about, but these tools do remove the pain of building, hot-reloading, compressing or obfuscating your code, but definetely there can be other raw way to do these, as what these are doing is providing you an abstraction.

How to properly override a core JS file in Magento2

We are attempting to override the behavior of Bundle Products in Magento2, specifically, to enable user defined quantities for Checkbox type products within the bundle.
We have written an extension, and followed instructions about how to replace a default JS component found here: http://devdocs.magento.com/guides/v2.0/javascript-dev-guide/javascript/custom_js.html
Our requirejs-config.js within our extension's frontend (app/code/Endertech/BundleExtended/view/frontend/) view looks like:
var config = {
"map": {
"*": {
'Magento_Bundle/js/price-bundle': "Endertech_BundleExtended/js/price-bundle"
}
}
};
This is having the effect of loading BOTH the core Magento2 price-bundle.js AND our modified version... and the customization we've added to our modified version is not executing... presumably because the Magento2 core version is loading first.
We expected for this revision to PREVENT the core version from loading in favor of ours.
Perhaps we are approaching the problem from the wrong direction, or have some other misunderstanding.
We are seeking a solution to have our modified price-bundle.js be loaded in lieu of the built-in that comes in the Magento Bundle module... or at least a way to override specific methods within and is required here (vendor/magento/module-bundle/view/frontend/requirejs-config.js).
If our approach is wrong, we'd be happy to be corrected!

Firefox SDK require regular JS files

Is there a way to include regular javascript files in the Firefox SDK background script?
If I just have a script file that defines some variables, include it and access those in the background script.
Its my understanding so far that they MUST be CommonJS modules. I am porting a Chrome Ext that also uses alot of common code with a mobile app, etc which I'd rather not try converting to CommonJS modules.
Is this possible?
Its my understanding so far that they MUST be CommonJS modules.
That's correct.
If you want to include standard JS files that are already structured in some way, you'd either have to inject them into a page worker, which will
Create a permanent, invisible page and access its DOM,
then send in and out the few variables needed and resulting, respectively, using port, as I explained in your last question.
Or you could use some sort of file concatenation (if you minify your files, this should already happen), then save this new JS file in the lib folder, and require/export those same variables.
These approaches only require you to input/output the variables that are needed externally from the system of files you already have in place, so it's less of a pain than converting each file to commonJS.
NB: I use Angular for my webapp, and have used some modules for both like so
var syncHelper = function() {
this.filter = function(objects, prop) {
// do stuff
}
this.consolidate = function(local, server, id) {
//more stuff
}
}
// app is my angular webapp var
if (typeof app==='undefined') syncHelper.call(exports);
else app.service('syncHelper', syncHelper);

Yui invalidate javascript browser cache with new release

I have YUI project that is mavenized. When we release new YUI code, it is not reflected right away in the browser, until you do SHIFT + REFRESH on browser.
I have been using YUI modules approach to load scripts like this:
YUI.GlobalConfig = {
modules: {
'manual-entry-util': {
fullpath: 'resources/js/common.js',
requires: [ 'node']
},
'user-perm-util' : {
fullpath: 'resources/js/userPermUtil.js',
requires: [ 'node', 'io-base', 'json', 'json-stringify']
},
'file-upload-custom' : {
fullpath: 'resources/js/fileUploadCustom.js',
requires: [ 'gallery-datatable-selection','event-custom', 'node']
},
'icsd-uploader' : {
fullpath: 'resources/js/icsdUploader.js',
requires: [ 'uploader', 'node']
},
'ui-util' : {
fullpath: 'resources/js/uiUtil.js',
requires: [ 'node']
}
}
};
I believe we need to modify the urls to have some sort of variable so that new code can be picked up by the browser.
Is there a way to automate this process via maven or some other tool. E.g. which can generate the hash value from the contents of the .js file and then add that to the url of .js file?
My approach has been to include a cache-busting value at the beginning of the path to your resources. An appropriate value might be the current abbreviated commit hash or revision number, or if using a CI tool, the current build number. Your build process would deploy all of your assets into a directory named with this value, so if your current commit hash was abcd1234, you would end up with files in something like resources/abcd1234/js/.
Your build process would need to also dynamically modify your YUI.GlobalConfig object, perhaps using token replacements, so that the YUI Loader could find your files there. This could be done in one spot by setting the base configuration option (see http://yuilibrary.com/yui/docs/yui/loader.html#configuration-options), but since you're specifying the fullpath for each file, you'd have to set each of these.
During development, you'd have to continue hard reloading your pages (as you're doing now with SHIFT + REFRESH), but your users will cache each version of your resources separately.
We use a variant of the answer from #blicksky. We built our own combo-loader as a servlet.
Firstly, we set up YUI as it's own Maven project. The version tag reflects the release of YUI, so your version would look like <version>3.17.2</version. We have an in-house repo, so any update to the YUI project gets published there. The YUI project just houses a copy of YUI in /src/main/resources/META-INF/resources. In this respect it's pretty similar to the approach taken by the WebJars project.
The Combo-loader takes care of concatenating the YUI files together for better loading performance and is also responsible for adding a cache-busting URL parameter. In production that parameter is the Build ID, but in development, that parameter can be a random number, so that the resources are loaded each time. We're using Spring on the server, so we use the Classpath to resolve YUI files that come from the YUI Maven project mentioned above. The basic gist is that our Servlet implements ResourceLoaderAware and can then use the ResourceLoader to pick up YUI files to serve up.
The approach has served us well and also allows us pretty fine-grained control of how the files are served, as well as improving load-times.

Resources