JS Marko (raptor templates) load dynamic template path in browser - javascript

I am trying to use Marko templates in a web application, and would prefer to be able to load pre-compiled templates dynamically. My (weak) understanding is that the suggested raptor-optimizer does static analysis to load all of the templates (as does browserify), and so wouldn't be able to bundle templates only referenced dynamically.
Is it possible to do this without having to hard code every possible template path that I might be interested in? Is it possible to not have to surrender the concat and minify steps to raptor-optimizer/browserify?
first_tmpl = require('marko').load(require.resolve('./tmpl/first.marko'))
second_tmpl = require('marko').load(require.resolve('./tmpl/second.marko'))
https://github.com/raptorjs3/marko#browser-side-rendering

Out of the box, Browserify only supports static code analysis for discovering and bundling dependencies. The RaptorJS Optimizer supports both static code analysis and declarative dependencies inside optimizer.json files. The RaptorJS Optimizer also supports glob patterns so that you can do the following inside an optimizer.json file:
{
"dependencies": [
"**/*.marko"
]
}
In most cases it is better to rely on discovering required templates via static code analysis.
I hope that helps.
--Patrick

Related

Using webpack and publicPath for static resources

The following question was rewritten, because I have now a working solution, but no answer to the question above.
The repository that shows different scenarios how to use resources packed with webpack is named example-webpack-dynamic-resources. It contains 3 modules:
inline: a solution, but not useful in my context (many resource files)
file: a solution by using the plugin webpack-require-from
public-path: no solution yet, shows how I would like to use __webpack?public_path__.
I think I have read any resource about webpack and publicPath and __webpack_public_path__, but I don't get it to work. I try to dynamically change the path to static resources, but it fails.
Here is my context:
I build a Javascript library that will be used on web pages (HTML, CSS, Javascript).
It provides a lot (>100) static resources to small image files, combined > 500 KB. Only a fraction of it will be used by the user looking at the web site.
Therefore I would like to pack the CSS into the bundle, but keep the image resources in a directory located on the server somewhere. The default path to it will be /img.
As long as I use the same structure (which means, images only under ROOT/img/**, everything is ok.
But the users of the library should be able to configure the path to the image resources on their will.
You will find all relevant files in my example repository example-webpack-dynamic-resources in the module public-path-resources.
webpack.js: Use file-loader for images, which are referenced in CSS files. CSS will be inlined by style-loader and css-loader.
src/public-path.js: Define the global variable with a default (no environment variable).
src/index.js: require first public-path, then the logic.
examples/exam1-root/index.html: Tries to use the assets in the sub directory lib, sets the value therefore to __webpack_public_path__ = '/lib/. Not working.
examples/exam2-different-dirs/index.html: Moves the library to a different dir (not relevant), but uses the originally defined directory pgnv-assets for the assets. Working.
examples/exam3-non-standard-dirs/index.html: Try to use instead my-assets as directory for the assets. Not working.
How could the __webpack_public_path__ defined at runtime in the index.html file?

How to concat and bundle JS files using webpack to be loaded in a script tag

I'm struggling to find a "quick" way to transition some legacy javascript files from assetic to webpack. I (think I) need to find a way to bundle a set of javascript files by simply concatenating them and not having webpack wrap it in a jsonp.
Our platform is built in Symfony, using twig templates and we've got most of our legacy javascript files loaded using assetic (it simply concatenates, and minifies), we've got newer javascript/typescript files bundled with webpack.
Naturally I want to remove all assetic dependencies and use webpack to bundle the old javascript. However, due to the way that webpack produces the bundles, it gets wrapped in the jsonp and any functions/variables defined in those javascript files are not available in global scope.
In an assetic world, our twig files are littered with these:
{%- javascripts
'%kernel.root_dir%/../vendor/twbs/bootstrap/js/bootstrap-transition.js'
'#MyBundle/Resources/js/legacy-1.js'
'#MyBundle/Resources/js/legacy-2.js'
filter="?uglifyjs2"
output="js/compiled/page-one.js" %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
Which concatenates and minifies them all. I'd like to replace this with a similar webpack version.
I've identified some approaches, but I'm not sure any of them are the best.
Use script-loader to get the scripts to load in global scope - Since script-loader uses eval which is disabled using CSP, this is out of the question
Rewrite each javascript file, exposing the members on the window. - This would probably be the easiest option but I really don't like the idea, and it goes against best practices.
Rewrite each javascript file, exporting the members, then use the expose-loader to load the files, then go through all the twig files and update the references to the members with the global namespace. This would take a lot of time, and I'd prefer not to do this if at all possible
I figured that I could simply configure a queryParameter and the file-loader to load each one, but I'd need a script tag per resource, and would lose out on the bundling nature. (I use a Symfony webpack bundle to generate an entries list for webpack, and provide twig functions for loading entries at runtime from the cdn)
<script src='{{ webpack_asset('%kernel.root_dir%/../vendor/twbs/bootstrap/js/bootstrap-transition.js?asFile') }}"></script>
<script src='{{ webpack_asset('#MyBundle/Resources/js/legacy-1.js?asFile') }}"></script>
<script src='{{ webpack_asset('#MyBundle/Resources/js/legacy-2.js?asFile') }}"></script>
So I'm looking for a way to concatenate the files together. Creating a separate entry file, and loading that as a file wouldn't be good enough as the requires/imports wouldn't be resolved.
I understand the webpack-concat-plugin would require me to define all of the various files to concat up front in the webpack config, which isn't really possible.
I haven't come across a loader that would replace the import '#MyBundle/Resources/js/legacy-2.js' with the content of that js file - but maybe I'm missing something.
I wonder if after all of this effort trying to find an easy solution is greater than the effort to rewrite the legacy javascript to use modules...
I found the following answers but they don't really help me:
Webpack - How to load non module scripts into global scope | window - This assumes I can define the files to concatenate up front. I have almost 100 different includes using assetic, almost all of them use different files.
Webpack - How to load non module scripts into global scope | window - eval is disabled by our CSP
Expose javascript globals bundled via webpack - As I mentioned, I don't really want to create 100 'entry' files just for this, and the webpack-raw-bundler also requires everything to be defined up front in the webpack config file.

Compile Typescript files into single js file without preliminaries

I'm pretty new to Typescript. I'm about to work on a Js project and I want to use Typescript because provides modularity features which helps me to maintain and develop the project more easily.
I put each class inside one single ts file and imported all of them in the main.ts file. I used --outFile flag to compile all of them into a single js file
but the problem is I want to finally compile them into a single js file and easily attach it to HTML file without any other preliminaries such as importing require.js! is there any way to do it without importing any other js files to the HTML document? if not, please suggest me an alternative way!
because I want to just compile all the stuff into one file like jquery.js file.
I used --outFile
Use outFile only if your code doesn't depend on any other library as it is straight concatenation.
the problem is I want to finally compile them into a single js file and easily attach it to HTML file without any other preliminaries such as importing require.js
This will only happen if you used a module aka import/export statement in your code. These require a module loader. outFile should not be used if you are using modules.
Thoughts
Personally I recommend commonjs with webpack
This is what I was looking for
https://www.typescriptlang.org/docs/handbook/gulp.html

Including Javascript Files (not module) in Kotlin

I have two Javascript files. I have some Kotlin code that generates a Javascript file. I also have a file (call it file.js) that depends on the generated javascript file from Kotlin.
Is there a way for me to include file.js in the Kotlin generated Javascript file using Gradle? Is there a setting that can append resource Javascript files into the generated output?
My motivation is to slowly transition my Javascript project into Kotlin, and due to the structure of the project, I cannot create a module. Just want to know if it is possible to do this and how.
You can use Gradle's Ant integration for that. Here's an example from Gradle forums:
task concat(type: SourceTask) {
source 'src'
include '**/*.txt'
outputs.file new File(buildDir, "full.txt")
doLast {
ant.concat(destfile: outputs.files.singleFile) {
source.addToAntBuilder(ant, 'fileset', FileCollection.AntType.FileSet)
}
}
}
This will concatenate a bunch of files into a single full.txt file - adapt it to your specific case and have the task execute prior to assembling your final build artifact.
I have to say that for Javascript builds Gradle's integration with tools like Gulp and Grunt (via plugins) may be an even better match for you - those tools can naturally handle simple JS file concatenation, but they also offer many more tasks useful for working with web technologies.

Bundler does not include script file

I am creating single page app using Ember.js with multiple javascript files, which are combined and minified using bundle feature in VS2012.
If I turn on minification (BundleTable.EnableOptimizations = true;), ember.js library (ember-1.0.0-rc.3.js) is not included into ember bundle. For clarification filename does NOT end with ".min.js" nor ".debug.js". My bundle definition looks like:
bundles.Add(new ScriptBundle("~/bundles/ember").Include(
"~/Scripts/handlebars-1.0.rc.3.js",
"~/Scripts/ember-1.0.0-rc.3.js",
"~/Scripts/ember-i18n.js",
"~/Scripts/localize/loc-slovak.js"));
and it is used on page using:
#Scripts.Render("~/bundles/ember")
I have suspicion for too large file (more than 28000 lines, 774 kiB). I tried to update nuget package Microsoft.AspNet.Web.Optimization to latest version, but id did not solve my problem.
.NET's Bundler breaks Ember RC3 if you minify it. It's also breaking Ember-Data. We had to include all Ember related scripts without bundling directly in the _Layout.cshtml for now while we work on a different solution (we'll likely include a different transform just for Ember):
<script type="text/javascript"
src="#Url.Content("~/scripts/ember-1.0.0-rc.3.min.js")"></script>
<script type="text/javascript"
src="#Url.Content("~/scripts/ember-data.min.js")"></script>
If you're using the SPA template(download | source), you should be fine as it's still using RC2; but if you update to RC3, then you'll have to modify the bundle config and the layout file according to this sample.
I didn't have time to send the PR to the SPA template yet, but I have updates for this issue (will do it tonight fo sho)
Another thing if you're using the SPA template: It comes with a HTML helper #Html.RenderEmber() to render the templates in the View file in debug mode. This method does not render the template names according to Ember conventions, so I've added another method for now (#Html.RenderEmberTemplates()). They should be in sync after the PR/merge.
The sample added in Myslik's repo is probably the most up to date at this point and I suggest that you take a look for reference.

Categories

Resources