I'm trying to import the javascript from a gem's folder with Rails 6 webpacker. I've seen this only done with 1 file per import. Is it possible to grab all files with *.js extensions for a gem?
javascript/packs/application.js.erb
import "<%= File.read(File.join(Gem.loaded_specs['active_storage_drag_and_drop'].full_gem_path, 'lib', 'assets', 'javascripts', 'active_storage_drag_and_drop/*.js')) %>";
Error
(erb):17:in `read': No such file or directory # rb_sysopen -/home/user.../active_storage_drag_and_drop../assets/javascript/active_storage_drag_and_drop/index.js
This package is available on NPM: https://www.npmjs.com/package/active_storage_drag_and_drop
I would instead do this:
yarn add active_storage_drag_and_drop
Then in your Webpack js file:
import * as ActiveStorageDragAndDrop from "active_storage_drag_and_drop"
window.ActiveStorageDragAndDrop = ActiveStorageDragAndDrop // needed as of v1.0.3
https://github.com/rossta/rails6-webpacker-demo/commit/ce1e8eb991b681574bdb7ce0ef33ae4e34b61dfd#diff-c0a98e77a42efd669302853444d5c362
I've created a working demo in a branch at https://github.com/rossta/rails6-webpacker-demo/tree/example/active_storage_drag_and_drop
Because the package's JS source makes assumptions about globals as of v1.0.3, assigning the imported var in your project JS appears
to be necessary until the package is updated.
You may still need the gem in your Gemfile for the Ruby-based dependencies.
Generally, I would not recommend trying to look up javascript dependencies provided by Ruby gems via the gem path in ERB. One of the advantages of moving to Webpack/Webpacker is that you should try to leverage NPM for your dependencies where possible.
Related
I would like to create a js library with Kotlin Multiplatform (an example of which is this project, where we have a webscocket server and a js client) which I will then build as a npm package and import in my Vue project (could be any other framework).
what I managed to do with chat project is:
build js sources with ./gradlew build
publish that via yarn publish (setting up remote registry url ofc)
add published package to package.json with (needed to update project name to #chat/client by hand in the generated package.json):
{
"name": "#chat/client",
"version": "0.0.1",
"private": false,
"workspaces": [
"packages/chat-frontend",
"packages/chat-frontend-test",
"packages_imported/kotlin/1.6.21",
"packages_imported/ktor-ktor-client-core-js-ir/2.0.0",
"packages_imported/kotlin-test-js-runner/1.6.21"
],
"resolutions": {},
"devDependencies": {},
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {},
"bundledDependencies": []
}
added #JsExport annotation on writeMessage in src/frontendMain/kotlin/main.kt
what I didn't manage is (in my Vue project):
import writeMessage, I exported in .kt file (it's visible in source, not exported though)
import anything via import * from '#chat/client'
or any other folder along '#chat/client/*'
use the generated files in any other way
The generated package structure is very odd:
~ ls build/js/*
build/js/package.json build/js/yarn.lock
build/js/node_modules:
... (npm dependencies from Kotlin/JS module)
build/js/packages:
chat-frontend chat-frontend-test
build/js/packages_imported:
... (Kotlin/JS dependencies)
~ ls build/js/packages/chat-frontend/*
build/js/packages/chat-frontend/package.json build/js/packages/chat-frontend/webpack.config.js
build/js/packages/chat-frontend/kotlin:
chat-frontend chat-frontend.js chat-frontend.js.map chat-frontend.meta.js
(chat-frontend contains package dir tree and a file frontend.kjsm)
build/js/packages/chat-frontend/kotlin-dce:
chat-frontend.js
ktor-*.js
kotlinx-*.js
... (compiler output ???)
build/js/packages/chat-frontend/node_modules:
... (webpack cli and dev-server files)
Do you have any clues, tips or an example project which does that? I've processed whole section of Kotlin/JS docs but there is no information on how to import Kotlin generated .js files in a js/ts project.
EDIT:
I've updated my fork of ktor-samples with Kotlin/JS build files: build-js folder and src/backendMain/resources/chat.js. Here's the link to chat folder of the fork project
I will try to help
Kotlin/JS has 2 kinds of compiler: legacy and IR. #JsExport affects only IR compiler. But from kotlin-dce folder, you use legacy compiler backend. In IR compiler, DCE (dead code elimination) is included into compiler and there is no folder kotlin-dce. You can change compiler kind in gradle.properties with kotlin.js.compiler=ir|legacy.
When you build project with IR, packages/*/kotlin will fully contain your library (similar with legacy's kotlin-dce)
Then you need to prepare appropriate package.json file with name and main fields (task :publicPackageJson could help with that, but check, if it is ok for your case)
Now in Kotlin/JS export works with packages. It means, that if you export io.ktor.samples.chat.frontend.writeMessage, it will be exported as io.ktor.samples.chat.frontend.writeMessage in js. So to import it, you need import io and then find necessary declarations.
import { io } from '#chat/client`
io.ktor.samples.chat.frontend.writeMessage("hello")
In the case of classical (non-IR) js backend usage and you use only non-private NPM dependencies then the only thing that you need is to compile your Kotlin/js library (via :compileKotlinJs task), generate package.json for your library (via :publicPackageJson) and your package could be published to NPM or another private repository (by yarn publish).
After publication, you will have the ability to set your library as a dependency in any js project. (Note that the name and version of your library will be placed inside package.json (generated by :publicPackageJson task)).
Also, you can check this discussion. Hope it will help you.
I've a npm package with the following three files in the dist folder (generated by webpack):
Inside the package.json file I've declated the sample.js file as the main one: "main": "dist/sample.js",.
Now I wan't to use this package in another project. Did I need to import all three files? Or should all work fine with one import like import aFunction from 'package-name'?
If there aren't any other weird dependencies, and sample.js is actually the entrypoint of the library (i.e. either you do everything inside it, or you make all the needed exports from it), it should work fine just as you wrote, i.e. import aFunction from 'package-name'.
Btw, is sample.js minified? As far as I remember, starting with Webpack v4 it does the minification automatically for production builds. But you might still want to doublecheck (read here for more info).
I am working on a project which is used typescript, vue and webpack together. I have created some components and i can use them by importing. However i have different js files in another root folder like site.js, ruler.js, color.js, speech.js, drware.js and etc. Schema is like below
+|dist
----build.js
+|src
----index.ts
+|main
----Header.vue
----Footer.vue
----Body.vue
+|lib
----site.js
----ruler.js
----drawer.js
----color.js
webpack config is getting index.ts from src folder which is shown above. When I don't use some functions (like jquery plugins or some special funciton) everything is fine. But when i use a functon from site.js webpack fives error like cannot resolve "ruler" from site.js
I have tried to concat by giving second entry in webpack.config.js but it didn' solve my problem. I wonder how to to resolve external js files in vue or ts files using webpack. I alson tried
require(""../src/site.js)
but it didn't work too.
Edit : If i concat the js files manually and give it as script source on html it works without problem but i cannot merge all files like or i don't want to use "gulp" to concat them
Have you tried including a script-loader into your webpack's configuration?
Webpack is a bundler, not a script loader itself. I would recommend you to follow webpack's official instructions to add a script loader.
Good luck!
I'm using webpack with babel-loader to organize my webdriverio scripts. Since I'm writing automated web-site testing scripts, I don't have a production environment per-se, so the point of using webpack is really just to organize my code chunks better and transpile my es6 code to es5 since node does not allow all es6 features.
I have a script: "../../../external/file-search.js" which I am requiring at the top of an index.js file. The point of file-search.js is to search through the directory and require all files in that directory using fs. This is what my index.js file looks like (located in ~/tasks/):
var fileSearch = require("../../../external/file-search.js");
var d = __dirname;
fileSearch(d);
when I run "webpack tasks test.js" webpack compiles file-search.js into my "test.js" file rather than requiring file-search.js and allowing me to use it's exported method in my index.js file. I will use file-search.js in all my index.js files so it's important to include it as a module. I've tried using externals but as far as I know, externals simply exclude certain modules from being compile/transpiled and try to bundle them into the final script. I actually want to require that script and use it right away in my index.js file. How can I require file-search.js and use it right away as part of my index.js file?
When using the Jasmine Rubygem, I find it extremely annoying that I have to conform to the generated directory structure which has a javascripts subfolder within the spec folder. I find it useless since I'm writing entirely in Javascript.
I find I can change this within the public folder by changing the generated jasmine.yml, however, this is not what I wanted since I still have to keep the javascripts folder with me.
Is there any way of customizing this folder structure?
Here's how I did this with jasmine gem 1.0.2.1:
1) Customize the jasmine_config.rb file to override the simple_config_file method to point to the correct yml file path. This file is initially generated at spec/javascripts/support/jasmine_config.rb. As seen on the github source (https://github.com/pivotal/jasmine-gem/blob/v1.0.2.1/lib/jasmine/config.rb), the method is hardcoded to use:
def simple_config_file
File.join(project_root, 'spec/javascripts/support/jasmine.yml')
end
I wanted to rename my 'spec' directory to 'test' so the top of my jasmine_config.rb file looks like this:
module Jasmine
class Config
def simple_config_file
File.join(project_root, 'test/javascripts/support/jasmine.yml')
end
end
end
2) Force rake to load the config file. I did this by adding the line:
require 'test/javascripts/support/jasmine_config.rb'
immediately after requiring jasmine in my Rakefile.
3) Update jasmine.yml (also in the support folder) to indicate where your javascript test files live. My yml file now ends with this:
# EXAMPLE:
#
# spec_dir: spec/javascripts
#
spec_dir: test/javascripts
Of course, you need to adjust that path "test" to be what you want.
I think this approach should work with the latest version of the gem, but this approach will break in the future if they change the interface of that Config class.
As of 2021, here's how to change the folder name when using the jasmine-browser-runner with NodeJS.
Install jasmine and setup the project:
npm install --save-dev jasmine-browser-runner jasmine-core
npx jasmine-browser-runner init
Rename the spec folder to test and edit jasmine-browser.json:
"specDir": "test"
Run the tests with this command:
npx jasmine-browser-runner runSpecs --config=test/support/jasmine-browser.json