Using Parcel 2 with Ruby on Rails - ruby-on-rails

How can I output the javascript file from Parcel, include this javascript file in Rails app/assets/javascripts/application.js, and ideally get it working with hot module reloading?
Alternatively, is this a bad approach, and do you recommend something more streamlined, that lets me use mostly traditional .html.erb Rails templates but sprinkle in ReactJS UI components here and there?
I was able to do this perfectly in Parcel 1 but I am finding that the setup is quite different in Parcel 2.
I am using the traditional Rails 5 application.html.erb templating.
My attempt so far with Parcel 2 has been to use the library tutorial in the Parcel documentation. I can mount the simplest React component to my Rails app but then if I try to import anything I get errors like require is not defined, and HMR is not working.
I'm not sure how much context to provide for this question. But if it helps, my previous setup with Parcel 1 was to have a separate npm app at the root folder (next to the Rails /app folder) which output a dist/index.js file using the npm script parcel start app/index.jsx --out-dir dist --public-url /assets/dist. This was added to the Rails assets via config.assets.paths << Rails.root.join('frontend') and included in app/assets/javascripts/application.js .
Now for Parcel 2 I removed the include in application.js and added <script type="module" src="/assets/dist/index.js"></script> in application.html.erb

There are two errors you're seeing that I might be able to help with:
Runtime errors like require is not defined. This would be expected if you set up parcel to output your javascript as a library target (as you indicated). Libraries are typically npm packages that are consumed by other projects. In this context, parcel will output a commonjs bundle (including require-based imports) that's intended to be processed by another bunder (maybe parcel again, or webpack) before it's ready to be executed in a browser. You probably want to build your javascript with a browser target instead, so that all dependencies are included without require statements to other packages.
Assuming your package.json for the parcel project currently looks similar to the the library tutorial, the way you'd do that would be to remove the "main": "path-to/my-root-javascript.js" field, and change the build script to parcel build path-to/my-root-javascript.js. There's also a bunch of ways to customize this - see the targets documentation.
HMR not working. If parcel is only in charge of bundling your javascript (and rails is building your html from templates), then the "normal" way that parcel does HMR won't work. This "normal" way would involve parcel injecting an HMR script in the html file that's its responsible for building and serving. But if Rails is taking care of the HTML, parcel can't do this automatically. Perhaps there is a way to configure rails to watch when parcel rebuilds the js bundle, and refresh the page?
This might be a bit of an onion-peeling exercise - it's hard to say if the above suggestions will solve it all end-to-end. If you can post a minimal reproduction of the issue (maybe a simplified version of your ruby + parcel project?) on github that shows the problem, I'm happy to troubleshoot it further.

Related

How to deploy angulardart 5.2 properly for production?

on the angulardart official website, I can not find any docs related to production deployment. I prefer command line way, so far I find out I can do webdev build to generate a build/ directory. But there are still some more questions:
I want to clarify what files I should deploy to the production server. I think they should be favicon.ico, index.html, main.dart.js, styles.css 4 files, right?
Why does it generate .build.manifest, .packages, packages/? two files and one directory which contains many directories and files. They are just confusing me. This is for production. Why do I ever want to have those files? Should I write a deploy script to simply auto-remove them?
It seems the generated main.dart.js is a minimized js file. But why are there many useless newlines in it? How to get rid of those useless newlines properly by using angulardart way? I can do that with gulp, but I don't want to use gulp if dart can handle this.
How to minimize html and css files properly by using angulardart way? for example, index.html and styles.css. Again, I can do that with gulp, but I don't want to use gulp if dart can handle this.
Thank you very much for your help.
Here you can find some of official doc :
https://webdev.dartlang.org/angular/guide/deployment

Adding Lodash to a new Rails 5.2 app with webpacker

So, using Rails 5.2beta (gem install rails --pre), if you create a new app via rails new myapp --webpack=react... how would I go about incorporating Lodash into my flow from there?
I've mucked around with babel-plugin-lodash and lodash-webpack-plugin to no avail.
The compile doesn't fail if I do something like import { _pick, _map } from 'lodash/array'; ... but those variables are undefined when trying to use them.
I'm a bit lost as I'm both new to webpacker & webpack, and a lot of existing examples seem to target an older version of webpack?
Anyway, thank you for any help...
UPDATE:
Ok, looks like you can just do import map from "lodash/map"
So where are you trying to use lodash from? By this I mean are you sure the files are getting compiled / processed by Webpacker, or are they getting processed via the Asset Pipeline?
On my webpacker project I realized that there's a problem: that yes, regular old Javascript compiled with the Asset Pipeline won't know about the NPM Modules included via Webpack. (or at least the require statements wouldn't work).
Because of this I made a hard rule: all javascript goes where webpacker expect it (app/javascript) and no Javascript goes in app/assets. We only use the asset pipeline for CSS (which works great in our case, as I still don't think React - our frontend framework of choice - has a good story around site wide CSS).

How can I change the default path to the `rails` script in my project, or remove that dependency?

In another question (Why does the Rails command force a help message for the new command?), I found that Rails needs the rails script to be in the script folder, in the root of my project, in order for it to be properly detected as an existing Rails projects, and allow me to use the various rails commands other then new.
I did this because I felt that the more popular moniker for including executable content in a repository to highlight available use cases is by using the name scripts. At least the pluralism in English should be appreciated!
Is there anyway to change which folder the main Rails executable looks for the project-included one?
I actually think it's a bit silly to include this rails executable in the project, and can be redundant. Maybe it's for customization, but I feel that could better be done in the configuration, environment, other .rb files. So also, could this just be removed somehow, and still have a functioning project through varied use of the main rails command.

Webpack plugin for rails assets compatible manifest

I'm trying to fully replace the rails asset pipeline with a webpack based pipeline. I've got the dev setup with the webpack-dev-server and hot reloading etc all working beautifully. Now what I'm trying to achieve is a compilation step for production that would mimic how rails compiles assets (digesting / generating a compatible manifest.json file) such that I can still use helpers like javascript_include_tag etc. This is where I'm stuck.
I've read lots of tutorials on using webpack with rails, but they all end up writing their own view helpers to load the assets. I'm trying to avoid this because I don't want extra overhead or for devs to need to understand a different pipeline. I also want config like asset_host= to work out of the box for using a CDN etc.
Ultimately, what I want is something similar to gulp-rev-rails-manifest that generates a rails-asset-pipeline compatible manifest file on compilation, but I haven't found a plugin (yet) that exists for Webpack. So...
is it possible to run a webpack build through a gulp stream using webpack only (ie not using gulp-webpack) so I can use the above gulp plugin. The reason I don't want to use gulp-webpack is that it takes over your entries / output etc and I find that whole setup confusing since this all already exists in webpack.config
Or
Does anyone have any decent resources on writing plugins for Webpack. It seems a bit of a black box to me and the official site has a menu section for "How to write a plugin" but it's not actually a link to anything.
Or
Is there actually a plugin that will do exactly this and I don't know how to search properly on the interwebs.
Any help is greatly appreciated :)
Running webpack in a gulp task is very simple:
var webpack = require('webpack');
var webpackConfig = require('./webpack.config');
gulp.task('webpack', function(done) {
webpack(webpackConfig, function(err, stats) {
done(err);
});
});
Note that the stats object provided to the webpack callback contains information about all assets emitted by webpack, so you could potentially use it to generate your own manifest.
Here are a few webpack plugins you might find useful:
https://github.com/sporto/assets-webpack-plugin
https://github.com/danethurber/webpack-manifest-plugin
https://github.com/diurnalist/chunk-manifest-webpack-plugin
While there is no official tutorial on how to create a plugin, there's still a Plugin API doc that describes the different interfaces your plugins can hook into. The webpack source and github contain a lot of webpack plugin examples.
Here's a very simple plugin that just logs assets:
module.exports = function() {
this.plugin('done', function(stats) {
console.log(stats.toJson().assets);
});
};

Importing Node Modules in to Rails

I'm working with Jasmine. I spotted this handy looking library: https://github.com/JamieMason/Jasmine-Matchers and I thought its collection of customer matchers would help me a lot.
Problem is, it's loaded with files common to Node applications, such as JSHint, Grunt, travis.yml etc
The project I'm working on, that would love these matchers, is a Rails application. I've tried dropping them into my assets/javascripts and requiring in application.js, but obviously, life isn't that simple.
What is the correct way to install these files, and integrate them with Jasmine in a Rails context? Is Bower the tool for the job? If so, what's the right procedure to adding JS dependencies/integrating them off the bat?
Author of Jasmine-Matchers here, the only file you need to load into your test environment is this one https://github.com/JamieMason/Jasmine-Matchers/blob/master/dist/jasmine-matchers.js.
The other files are part of the development repo, I'll open an issue to have those excluded from npm/bower packages to save confusion.
You should be able to copy that file to your assets/javascripts directory, then embed it after Jasmine but before your tests.
Please comment if I've missed anything out here.
I was also trying to use Node modules inside my Rails application and the easiest way I found to achieve it was through browserify-rails gem.
The installation is pretty straightforward, just follow the getting started section and everything should be working. :-)

Resources