Error when trying to import npm package (easyMDE) in application.js - (Uncaught ReferenceError: EasyMDE is not defined) - ruby-on-rails

Im trying to include easyMDE in my rails 6 project. I was including it from an external source before and that worked (via unpkg.com). To improve loading times I wanted to include it into my project via yarn.
I did the following steps:
yarn add easymde --save
In application.js:
require("easymde");
But when reloading the page I get the following error:
Uncaught ReferenceError: EasyMDE is not defined
When I run webpack-dev-server I see that easymde.js gets compiled:
Built at: 08/11/2020 3:16:09 PM
Asset Size Chunks Chunk Names
js/application-caadc00338c3578fee39.js 1.2 MiB application [emitted] [immutable] application
js/application-caadc00338c3578fee39.js.map 1.39 MiB application [emitted] [dev] application
js/easymde-1f6737d8a160c1180536.js 872 KiB easymde [immutable] easymde
js/easymde-1f6737d8a160c1180536.js.map 805 KiB easymde [dev] easymde
manifest.json 675 bytes [emitted]
ℹ 「wdm」: Compiled successfully.
application.js:
// 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.
require("#rails/ujs").start()
require("turbolinks").start()
require("#rails/activestorage").start()
require("channels")
// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)
require("easymde")
package.json:
{
"name": "logbook_v2",
"private": true,
"dependencies": {
"#rails/actioncable": "^6.0.0",
"#rails/activestorage": "^6.0.0",
"#rails/ujs": "^6.0.0",
"#rails/webpacker": "4.2.2",
"easymde": "^2.11.0",
"turbolinks": "^5.2.0"
},
"version": "0.1.0",
"devDependencies": {
"webpack-dev-server": "^3.11.0"
}
}
Let me know if you need any more code. :-)
Update
Here is the file where I use the editor:
<%= render "components/sidebar" %>
<div class="form-wrapper post-form-wrapper">
<%= form_with model: #post, class: 'form post-form' do |f| %>
<%= f.text_field :name, placeholder: 'title', class: 'field post-field' %>
<%= f.text_area :content, id: 'mde' %>
<%= f.submit 'create post', class: 'form-button post-form-button' %>
<%end%>
</div>
<script type="text/javascript" charset="utf-8">
var easyMDE = new EasyMDE({
element: document.getElementById("mde"),
placeholder: "Write your post here...",
autosave: {
enabled: true,
uniqueId: <%= current_user.id %>
},
blockStyles: {
code: "~~~"
},
minHeight: "calc(100vh - 320px)",
renderingConfig: {
codeSyntaxHighlighting: true
},
promptURLs: true,
toolbar: ["bold", "italic", "strikethrough", "heading", "|", "code", "quote", "clean-block", "|", "link", "image", "|", "unordered-list", "ordered-list", "|", "preview", "side-by-side", "fullscreen", "|", "guide"]
});
</script>
If I put in import * as EasyMDE from 'easymde'; (suggested by #Ninh Le) at the beginning of the script I get this error: Uncaught SyntaxError: import declarations may only appear at top level of a module

Easymde using module.exports, you can find it here
So to use it in with yarn and rails 6 I think the way is in js file:
import * as EasyMDE from 'easymde';
var easyMDE = new EasyMDE({element: document.getElementById('my-text-area')});
Edit: To make it can call globally, call this in application.js file
import * as EasyMDE from 'easymde';
window.EasyMDE = EasyMDE;

Related

Action Text [Rails 7 Error] vanishing field

Trying to isolate an error I'm getting with the basic setup of a new blog site using the below just so I can test Action_Text for the create blog section.
Every-time i create the below- it works great until i change the <%= form.text_area :content %> to <%= form.rich_text_area :content %> then the text area vanishes????
package.json
{
"name": "app",
"private": "true",
"dependencies": {
"#hotwired/stimulus": "^3.1.0",
"#hotwired/turbo-rails": "^7.1.3",
"#popperjs/core": "^2.11.5",
"#rails/actiontext": "^7.0.3-1",
"bootstrap": "^5.2.0",
"bootstrap-icons": "^1.9.1",
"esbuild": "^0.14.54",
"sass": "^1.54.3",
"trix": "^2.0.0-beta.0"
},
"scripts": {
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets",
"build:css": "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules"
}
}
rvm gemset create project
rails new project --css bootstrap
rails g scaffold blog title:string content:text
Rails db:migrate
Rails action_text:install
Rails db:migrate
class Blog < ApplicationRecord
validates_presence_of :title
has_rich_text :content
end
<%= form.rich_text_area :content %>
I have searched for days online, tested, broken this multiple times and still cant find a solution.
Any assistance would be great.
Thank you

Rails 7 accessing pinned libraries

importmap.rb includes
pin "javascript-autocomplete", to: "https://ga.jspm.io/npm:javascript-autocomplete#1.0.5/auto-complete.js"
And, following the rails guides, application.js was amended with
import "javascript-autocomplete"
although uncertainty about the syntax remains. Also attempted, as the script defines var autoComplete was
import autoComplete from "javascript-autocomplete"
in either instance, while the header shows:
<script type="importmap" data-turbo-track="reload">{
"imports": {
"application": "/assets/application-333b944449a4c540424142c36f01f97feebd58f2f41d10565ecfde32cb315110.js",
"#hotwired/turbo-rails": "/assets/turbo.min-e5023178542f05fc063cd1dc5865457259cc01f3fba76a28454060d33de6f429.js",
"#hotwired/stimulus": "/assets/stimulus.min-900648768bd96f3faeba359cf33c1bd01ca424ca4d2d05f36a5d8345112ae93c.js",
"#hotwired/stimulus-loading": "/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js",
"javascript-autocomplete": "https://ga.jspm.io/npm:javascript-autocomplete#1.0.5/auto-complete.js",
[...]
}
the body has
<%= javascript_tag do %>
var demo1 = new autoComplete({
[...]
});
<% end %>
which fails to run: Uncaught ReferenceError: autoComplete is not defined
so the script is not being accessed.
So where is this lacking?

Standalone React components with Rails6 / Webpacker

I'd like to know how to / [accepted way] to add standalone react components to specific pages in rails, using webpacker. The use case is that I have a Rails6 app that I intend to use Rails functionalities for the view, instead of a full React SPA. I would, however, like to use specific custom react components in specific rails views. The app has webpacker installed and configured for react.
Questions I have:
is react-rails the right gem / pattern for this usage? I have tried using it and it does perfectly fill the use case, but I was wondering if it can be done without adding this gem since it since it seems like webpacker itself has react support.
Is it required that the webpacker <%= javascript_pack_tag => should always go in an application layout (head tag), and dynamically render a pack to the end of the body(appendChild), like the examples say? I'd rather include the pack tag in a view, and have it render directly to a div I've specified. (code for this below)
How does one send react props to a standalone react component that is rendered by the <%= javascript_pack_tag => ? Would the component have to be written to fetch any data it needs on mount?
Things I've tried:
I looked through the documentation for webpacker, and as many of the issues I could find using the keywords "standalone" and "react" and couldn't find anything.
Sample project below: it works.. but I'm not sure if it's the right way to do this and I'm not sure how to address question 3 from above (regarding passing props)
Initialize
rails new petstore --webpack=react
bin/rails generate scaffold Pet pet_type:string pet_name:string
bin/rails db:migrate
package.json
{
"name": "petstore",
"private": true,
"dependencies": {
"#babel/preset-react": "^7.12.10",
"#rails/actioncable": "^6.0.0",
"#rails/activestorage": "^6.0.0",
"#rails/ujs": "^6.0.0",
"#rails/webpacker": "5.2.1",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"prop-types": "^15.7.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"turbolinks": "^5.2.0"
},
"version": "0.1.0",
"devDependencies": {
"webpack-dev-server": "^3.11.2"
}
}
config/webpacker.yml
default: &default
source_path: app/javascript
source_entry_path: packs
public_root_path: public
public_output_path: packs
cache_path: tmp/cache/webpacker
webpack_compile_output: true
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
additional_paths: []
# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
# Extract and emit a css file
extract_css: false
static_assets_extensions:
- .jpg
- .jpeg
- .png
- .gif
- .tiff
- .ico
- .svg
- .eot
- .otf
- .ttf
- .woff
- .woff2
extensions:
- .jsx
- .mjs
- .js
- .sass
- .scss
- .css
- .module.sass
- .module.scss
- .module.css
- .png
- .svg
- .gif
- .jpeg
- .jpg
development:
<<: *default
compile: true
# Reference: https://webpack.js.org/configuration/dev-server/
dev_server:
https: false
host: localhost
port: 3035
public: localhost:3035
hmr: false
# Inline should be set to true if using HMR
inline: true
overlay: true
compress: true
disable_host_check: true
use_local_ip: false
quiet: false
pretty: false
headers:
'Access-Control-Allow-Origin': '*'
watch_options:
ignored: '**/node_modules/**'
test:
<<: *default
compile: true
# Compile test packs to a separate directory
public_output_path: packs-test
production:
<<: *default
# Production depends on precompilation of packs prior to booting for performance.
compile: false
# Extract and emit a css file
extract_css: true
# Cache manifest.json for performance
cache_manifest: true
app/javascript/components/PetAnimation.js
import React from "react";
import PropTypes from "prop-types"
class PetAnimation extends React.Component {
constructor(props) {
super(props);
this.state = {
petType: props.petType,
};
}
render() {
return (
<div>Cute Pet Animation based on Pet Type and other imported libraries</div>
)
}
}
PetAnimation.propTypes = {
petType: PropTypes.string
};
export default PetAnimation;
app/javascript/packs/pet_animation.js
import React from 'react'
import ReactDOM from 'react-dom'
import PetAnimation from "../components/PetAnimation";
document.addEventListener('DOMContentLoaded', () => {
const rootElement = document.getElementById("pet-animation");
if (rootElement != null) {
ReactDOM.render(<PetAnimation/>, rootElement)
}
})
app/views/pets/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Pet type:</strong>
<%= #pet.pet_type %>
</p>
<p>
<strong>Pet name:</strong>
<%= #pet.pet_name %>
</p>
<p>
<%= javascript_pack_tag 'pet_animation', 'data-turbolinks-track': 'reload' %>
<div id="pet-animation"></div>
</p>
<%= link_to 'Edit', edit_pet_path(#pet) %> |
<%= link_to 'Back', pets_path %>
... and it works, sort of:

Bootstrap JS functions not loading in Rails 6/Webpacker

Climbing the learning curve with Webpacker and Rails 6.
I've installed Boostrap 4 using Yarn and Webpacker. When I try play with Bootstrap components in a browser's JS console then I get: TypeError: $.fn.button is undefined.
If I remove the Yarn installation add a Bootstrap CDN link in the head of the HTML (the old way) everything works fine. When I remove the CDN links and revert to using Webpacker I get back to the error above.
Here is my Webpacker setup:
// package.json
{
"name": "depot",
"private": true,
"dependencies": {
"#rails/actioncable": "^6.0.0-alpha",
"#rails/activestorage": "^6.0.0-alpha",
"#rails/ujs": "^6.0.0-alpha",
"#rails/webpacker": "^4.0.7",
"bootstrap": "4.2.1",
"jquery": "^3.4.1",
"popper.js": "^1.15.0",
"turbolinks": "^5.2.0"
},
"version": "0.1.0",
"devDependencies": {
"webpack-dev-server": "^3.8.0"
}
}
// enviornment.js
const { environment } = require("#rails/webpacker");
const webpack = require("webpack");
environment.plugins.append(
"Provide",
new webpack.ProvidePlugin({
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery',
Popper: ["popper.js", "default"]
})
);
module.exports = environment;
// application.js
require("#rails/ujs").start();
require("turbolinks").start();
require("#rails/activestorage").start();
require("channels");
require("jquery");
require("bootstrap");
import "./src/application.scss";
# layouts/application.html.haml
!!!
%html
%head
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}
%title Depot
= csrf_meta_tags
= csp_meta_tag
= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'
Is there something I should be doing to export the Bootstrap functions to the global namespace?
Found a forum where this was discussed: https://gorails.com/forum/how-to-use-bootstrap-with-webpack-rails-discussion
They mentioned it could be caused by having jQuery loading multiple times, with the latest declaration preventing Bootstrap's JS from loading. I couldn't find any evidence of this in my project.
For me the fix ended up being a few lines added to the webpack entry point that exposed jQuery to the browser:
# packs/application.js
import JQuery from 'jquery';
window.$ = window.JQuery = JQuery;
I noticed even I removed require 'jquery' from applications.js, jquery still appears in the compiled application.js, so I removed this from enviroment.js
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery',
and add this to application.js
import JQuery from 'jquery';
window.$ = window.JQuery = JQuery;
restart rails server, it works!
If you want to know why see this answer

SyntaxError occurs when reading js.erb file with webpacker

I'm currently developing with Rails5 and React.
And to use React, we use a gem called react-rails, and this gem uses webpacker.
At that time, in React, js.erb file was created to refer to the image precompiled with assets.
The information I looked up on the net had rails-erb-loader, so it should have been readable.
However, SyntaxError occurred.
I will write the details below.
ErrorLog
# ./bin/webpack-dev-server
~~~
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /home/myproject/app/javascript/components/sample.js.erb: Unexpected token (1:1)
> 1 | <% helpers = ActionController::Base.helpers %>
sample.js.erb
<% helpers = ActionController::Base.helpers %>
export const png_path = "<%= helpers.image_path('sample.png') %>"
package.json
{
"name": "Sample",
"private": true,
"dependencies": {
"#babel/preset-react": "^7.0.0",
"#rails/webpacker": "^4.0.7",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"lodash": "^4.17.14",
"prop-types": "^15.7.2",
"rails-erb-loader": "^5.5.2",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"react_ujs": "^2.6.0",
"reactjs-popup": "^1.4.1"
},
"devDependencies": {
"webpack-dev-server": "^3.8.2"
}
}
How can I solve this error?
We will wait for the answer.
This issue was not resolved. Sorry

Resources