I installed Webpacker gem into my Rails app and have difficulties to import JS and CSS files from assets folder to app/javascript/packs folder.
I'm mentioning that app/javascript/packs/application.js looks like this:
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
console.log('Hello World from Webpacker')
and it works properly(in console I get this "Hello World.." text.)
I tried to copy, for example jquery.slimmenu.js into packs folder and to include it like this:
//= require jquery.slimmenu.js
but it's not finding in console, there is just application.js and bunch of 404 not find JS and CSS files
your main.js file can be in any directory in app/javascript
for example, create app/javascript/components
then add in your application.js
import 'jquery'
require("../components/main");
then in your HTML add
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
and script from application.js must be loaded
Related
I have a Rails 7 app where I have JS files in /app/javascript/..., including application.js The application.js file just looks like:
import "./application/first"
import "./application/second"
etc
I then use esbuild and npm run watch (or npm run build) to compile the JS into one file, outputting it to /app/assets/javascripts/application.js
This all works locally, but when I go to deploy the website in production, it has the application.js file that looks like this:
import "./application/first"
import "./application/second"
etc
That doesn't work at all.
This is being included with a normal JS include tag <%= javascript_include_tag "application", media: :all, type: :module, defer: true %>
It is like the compiled file is being overwritten by some part of the production deployment? How can I have it use the compiled file that I built?
I have a Rails 6 app in which I am trying to use webpacker. I was using it succcessfully and importing all packs in my application.js file but instead now I just want to import the application.js file that has jquery and bootstrap in it, and dynamically load the correct pack based on the controller.
For instance, my previous configuration was
import "bootstrap"
require("#rails/ujs").start()
require("turbolinks").start()
require("#rails/activestorage").start()
require("channels")
require("jquery")
require("../packs/classrooms")
require("../packs/lunch_choices")
require("../packs/events")
require("../packs/users")
What I'd rather do is remove all packs from the application.js file and just import the correct pack dynamically like so...
Application.html.erb
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag "#{controller_name}", 'data-turbolinks-track': 'reload' %>
If I view the source code when I reload the page and restart the server, I see that the pack does load, however, I get the following error.
$(...).modal is not a function
Since the application file is being loaded first and that's the one that contains jquery, why am I getting this error? This was working when I was including all packs in application.js, but now that I want to split by the pack it does not.
Here is my environments.js file - this has never changed since setting up my app.
const { environment } = require('#rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
jquery: 'jquery',
Popper: ['popper.js', 'default']
})
)
module.exports = environment
Each pack is a separate dependency graph. Without extra configuration, the graphs are not shared. I would guess you’re either accessing a function on the wrong dependency graph or possibly clobbering one instance of jQuery for another in the global scope.
Splitting your code into multiple packs, while possible, is error-prone and works against the way webpack was intended to be used.
Try consolidating everything into just one pack and splitting code with dynamic imports instead. Your “page-specific” code would live in another folder, like app/javascript/pages, and might be imported conditionally, based on the presence of a certain DOM element, for example. This achieves the goal of producing smaller bundles from one pack while keeping all your code in the same dependency graph.
https://webpack.js.org/guides/code-splitting/
How can I precompile and import a javascript file, while keeping it in the same folder as the views its associated with?
For example, I'd like to keep companies.js inside the same /view directory as my other company views
For example:
/app/views/companies/_form.html.erb
/app/views/companies/index.html.erb
/app/views/companies/new.html.erb
/app/views/companies/edit.html.erb
/app/views/companies/companies.js <--- like this
This allows better organization than a large number of javascript files in /app/assets/javascripts/.
I've seen it done before, but I've been unable to replicate it now.
Using <% javascript_include_tag 'companies' %> tries to find the file in /assets/javascripts/.
Try change the manifest file in app/assets/config/manifest.js to compile .js in view's folders.
E.g
//= link_directory ../javascripts .js
add this with the path to your view folder
Is this a good practice to require assets located under public folder? e.g. I have lots of javascript under public/mythirdparyjs folder and I want to make these javascript files available for only specific page, what will be the best way to do this?
Thirdparty js files should be in your vendor folder. Once you precompile them for production they will be then moved into your public folder automagically. To call certain files on specific pages you need to remove the require_tree directive and also pay attention to which files are called in your application.js asset file. At the bottom of every view page (html.erb) you can add the following to run only page specific js:
<%= content_for :javascript do %>
<script type='text/javascript'>
YOUR FUNCTIONS HERE
</script>
<% end %>
Then in your application/layout view at the bottom before the closing body tag you should add:
<%= javascript_include_tag params[:controller] if Rails.application.assets_manifest.assets["#{params[:controller]}.js"] %>
<%=yield :javascript %>
This will then run any js on a page by page view basis and include any require statements for any files in the corresponding controller's js asset file.
UPDATE to address comment: If you have a gem you installed and then need to require certain js files, these should be required from your app/assets/javascripts folder in either the application.js file (if you want that gem to be usable throughout your application) or in the controller specific js file if you only need that functionality on a few pages. For example, the angular gem is probably used throughout your application so you would add the //=require statement to the application.js file in your app/assets/javascripts folder. If you manually download some js libraries you should put them in the vendor/javascripts folder however you still require them in your app/assets/javascripts folder files wherever needed.
So running Rails 3.2. In my assets/javascripts folder I have the file "main.js.erb". The contents of this file are as follows:
$(function(){
$(document).load(alert("Hello"))
})
My application.js file is just the default generated after an install initiated with 'rails new'.
Any ideas as to why the load event is not being triggered?
Since your application.js is just the default, you probably haven't included the file for usage.
Following are different ways you can include the file:
In app/assets/javscripts/application.js
//= require main
In your template file or layout file eg. app/views/layouts/application.html.erb
<%= javascript_include_tag "main" %>
For further details please refer to The Asset Pipeline RailsGuides.