I'm an inexperienced web dev, and especially so when it comes to JavaScript. Lately I've been trying to fix that, and since Laravel's my framework of choice I'm trying to change from the "old" style of:
<script src="script1.js"></script>
<script src="script2.js"></script>
…
to something better. And using Laravel, the logical step is using Mix, which relies on Webpack.
After a lot of trial and error, I've managed to get the basic setup working. I have a settings.js file for changing the modules' default settings when necessary, and an app.js file for custom functions I'd like to make available on every page. I'm also separating the vendor modules to a vendors.js file.
So the bootstrap.js file has:
window._ = require('lodash');
window.$ = window.jQuery = require('jquery');
[...]
require('bootstrap-datepicker');
require('bootstrap-year-calendar');
The webpack.mix.js file has:
mix.autoload({ jquery: ['$', 'jQuery', 'window.jQuery']});
mix.webpackConfig({ resolve: { alias: { jquery: "jquery/src/jquery" }}});
mix.js([
'resources/js/app.js',
'resources/js/settings.js'
], 'public/js')
.extract([
'lodash',
'jquery',
[…]
'bootstrap-datepicker',
'bootstrap-year-calendar'
]);
And the master layout has the following scripts right before `:
<script src="{{ mix('/js/manifest.js') }}"></script>
<script src="{{ mix('/js/vendor.js') }}"></script>
<script src="{{ mix('/js/app.js') }}"></script>
This setup seems to be working, but there's one last issue I just can't seem to figure out. I also add some javascript on specific pages, for functionality limited to those pages (initialising pickers with non-default settings, custom form behaviour, etc). So some pages have an extra <script type="text/javascript"> [custom code] </script> section before </body>.
However, code there doesn't have access to modules: $('.input-daterange').datepicker(); should initialise an input as a bootstrap-datepicker instance, but it doesn't. Of course, using the "old style" it worked. Now, I'm getting a TypeError: undefined is not a function (near '...$('.input-daterange').datepicker...') error.
So my issue is the following: how can I import the necessary modules to be used in the script embedded in the HTML file?
P.S.: when I was pretty much finished writing this question, I happened to stumble on the solution. I decided to post it nevertheless because a) it might help someone else, and b) if there's a better way to approach this, I'd love to hear about it.
Doing the import not on the embedded javascript, but on either my app.js or settings.js files, made it work:
import 'bootstrap-datepicker';
import 'bootstrap-year-calendar';
However, making the imports on settings.js rather than app.js seems to cause some issues, as it broke some separate functionality. I'm not sure if it's because app.js is listed first in the webpack.mix.js file (as shown below), but nevertheless the file where you make the imports does matter.
mix.js([
'resources/js/app.js',
'resources/js/settings.js'
], 'public/js')
Related
I am bundling 6 different modules together in Webpack. One of then is Mustache.js.
The Mustache templates live inside the HTML page. They are not in a separate file. Now when I load my page ... I get this error ...
This is my app.js file
require('mustache');
require("./js/modules.js");
require("./js/custom.js");
require('owl.carousel');
require('bootstrap');
require("expose-loader?$!jquery");
I have tried changing the order, but nothing is working.
The 'modules.js' file has a dependency on 'mustache'. So I went into the modules.js file and added require('mustache'); at the top in that file, but nothing changed. Do I need to add any additional configuration to my webpack.config.js file ?
If I take the Mustache.js modules out of the bundle and load it normally on the html page like <script src="js/mustache.js"></script> then everything works fine.
Can someone please advise how can I include this module in the bundle ? Already wasted so many hours trying to make this work, but to no avail. Many thanks in advance.
It sounds like it's working when not bundled because you reference the script directly in the DOM and Mustache is added to the global scope, in this case window.Mustache.
In your app.js or any other 'bundled' script that is referencing Mustache you'll need to require and assign to a variable:
var Mustache = require('mustache');
I'm building a NW.js app, currently with babel-standalone and React. I can use ES6 import, but ES6 export on the other hand does not work, console spits out unexpected token export. What's going on?
index.html:
<html>
<head>
<meta charset="utf-8">
<script src="assets/react.min.js" charset="utf-8"></script>
<script src="assets/react-dom.min.js" charset="utf-8"></script>
<script src="assets/babel.min.js" charset="utf-8"></script>
</head>
<body>
<script type="text/babel" src="script/App.js"></script>
</body>
</html>
(yes, Babel indeed works, since React stuff inside runs OK)
In app.js:
import Lib from "./script/lib.js";
(and it's indeed exporting lib.js correctly, since that is the file responsible for the error)
In script/lib.js:
export default class {...};
I'm aware I can use Node modules instead, or even HTML script loading, but that's beside the point. I want to know why export doesn't work even if Babel doesn't seem to be broken, and even import works fine.
The problem is that Babel doesn't see files that were loaded via require, and they are loaded as they are, without transpilation.
There can be several ways to work this around, but the easiest one will be using Babel at build step.
Process your source code and then load processed code nw.js environment. The example how to do that you can find at this boilerplate project
I'm working on an admin panel built on top of AdminLTE template. The template depends on jquery, bootstrap and some other custom plugins that must be previously included using script tags in document head.
I'm using Jspm to manage libraries, some libraries like Toastr will require jQuery as a dependency, and will install and load another copy of jQuery.
I'm trying to figure out how to configure SystemJS in order to:
a) Tell SystemJS that I don't need install another copy of jQuery and
b) avoid duplicate loading of jQuery, since it's a global dependency that was previously loaded. How to achieve this?
<script src="jquery.min.js"></script>
<script src="bootstrap.min.js"></script>
...
<script src="system.js"></script>
<script>
System.config({
"map": {
"jquery": window.jQuery //???
}
});
</script>
<script>
System.import('main').
</script>
Looks like you want to use System.set
System.set( 'jQuery', System.newModule({'default': window.jQuery }) );
This assumes the global is expected to be the 'default'. You can also specify other exports as well by passing in more key / values to System.newModule.
If you can, it would be better to import your globals like other scripts because globals can have dependencies and systemjs can manage the load order for you through meta config setup
Problem: I have jQuery datepicker in react app, which has to be localised in different languages(30 lang). I downloaded all the i18n file from the link (https://github.com/jquery/jquery-ui/tree/master/ui/i18n) but it has to be included as <script> tag.
Question: Is there a way to import this file? using webpackand commonjs?. I am using es6 import. Is there a way to bundle them all and import in the on file?
any suggestions are appreciated.
Edit:
Yes there's a way:
You can create a javascript function that takes the path as a parameter and creates these HTML lines:
<script src="js/datepicker-in-all-languages/datepicker-af.js"></script>
<script src="js/datepicker-in-all-languages/datepicker-ar-DZ.js"></script>
<script src="js/datepicker-in-all-languages/datepicker-ar.js"></script>
...................and for all other 30 languages................
And you'll just have to call this:
loadLib("datepicker-in-all-languages/datepicker-af");
loadLib("datepicker-in-all-languages/datepicker-ar-DZ");
loadLib("datepicker-in-all-languages/datepicker-ar");
Edit:
Also take a loot at Grunt which is meant for the same purpose.You can setup grunt to watch the folder of the scripts and concat/minify them into a single file, then you just have to include that in your HTML file.:
GRuntJS usage(According to their official page): With literally hundreds of plugins to choose from, you can use Grunt
to automate just about anything with a minimum of effort.
Edit:
There is also a minified file of jQuery ui i18n which is being hosted by google. You can use it in single <script> tag : http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/i18n/jquery-ui-i18n.min.js . I found it in answers here here.
I'm confused about my r.js optimised script. I imagine the answer to my question is in the documentation but I think I'm going doc-blind from staring at it too long.
My application has a directory structure like this
-index.htm
-js/app.js
-js/init.js
-js/appname/*.js
When in non-optimised mode index.htm contains the following line:
<script type="text/javascript" data-main="js/app" src="js/lib/require-2.1.11.js"></script>
and everything works fine. My abridged js/app.js script looks like this:
requirejs.config({
baseUrl: 'js',
paths: {
...
}
});
require(['init']);
When I build the optimised script I specify js/app.js as the mainConfigFile and everything builds as expected. However when I update my script tag's data-main attribute to the build product my application doesn't initialise.
If I manually execute require(['init']) in the console it starts up as expected. Because r.js is using js/app.js as its config file that doesn't get included in the optimised script, which means my require(['init']) also doesn't get included.
I thought I could fix this by moving require(['init']) to the end of js/init.js and this does fix the optimised build (it initialised as expected), but now that the call isn't in js/app.js the non-optimised version never initialises. If I include the call in both files I get an error.
How can I ensure my first module is required after either the optimised or non-optimised file(s) are loaded? I don't understand how I'm supposed to make that first call after my first module's dependencies have fully loaded.
Because r.js is using js/app.js as its config file that doesn't get included in the optimised script
Well, then modify the build config you pass to r.js so that js/app.js is included in the final optimized bundle. There's nothing that forbids you from including the file you point to with mainConfigFile in the final bundle.