after phoenix 1.3 upgrade app.js are not loaded - javascript

I updated my phoenix 1.2 to 1.3 follwing the phoenix upgrade description.
Now assets/js/app.js can't be loaded:
Uncaught Error: Cannot find module 'js/app' from '/'
After debugging the problem, I found that the expected module is app not js/app.
When I change the module name in the brunch-config.js autoRequire modules to ["app"] instead of ["js/app"] it works. I don't understand what is the problem or what I did in my app, that the default settings don't work.
Here my assets/brunch-config.js
exports.config = {
// See http://brunch.io/#documentation for docs.
files: {
javascripts: {
joinTo: "js/app.js"
},
stylesheets: {
joinTo: "css/app.css",
order: {
after: ["../priv/static/css/app.css"] // concat app.css last
}
},
templates: {
joinTo: "js/app.js"
}
},
conventions: {
assets: /^(static)/
},
// Phoenix paths configuration
paths: {
// Dependencies and current project directories to watch
watched: ["static", "css", "js", "vendor"],
// Where to compile files to
public: "../priv/static"
},
// Configure your plugins
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
ignore: [/vendor/]
},
copycat: {
"fonts": ["node_modules/font-awesome/fonts"] // copy node_modules/font-awesome/fonts/* to priv/static/fonts/
},
sass: {
options: {
includePaths: [
"node_modules/bootstrap-sass/assets/stylesheets",
"node_modules/font-awesome/scss"
], // tell sass-brunch where to look for files to #import
precision: 8 // minimum precision required by bootstrap-sass
}
}
//sass: {
// mode: "native" // This is the important part!
// },
},
modules: {
autoRequire: {
"js/app.js": ["js/app"]
}
},
npm: {
enabled: true,
globals: {
$: 'jquery',
jQuery: 'jquery'
}
}
};
And my assets/js/app.js is here:
import "phoenix_html"
import "./datetimepicker"
thanks for any help, tipps or ideas to understand/solve the problem.

The problem is related to the brunch version.
updating brunch to:
brunch#2.10.10
solved the problem.

Related

What is the proper way of bundling in node dependencies with rollup?

So I was trying to bundle in a bunch of external package dependencies using roll-up, like three JS and deck.gl. Right now I have a rollup config file set up like so, one to build just the code I have written and another that bundles in all the dependencies :
import externals from "rollup-plugin-node-externals";
export default [
{
input: "./Src/index.js",
output: [
{
file: "./Build/pgl.js",
format: "iife",
plugins: [
externals({
deps: true, // Dependencies will not be bundled in
}),
],
},
{
file: "./Build/pgl_module.js",
format: "iife",
plugins: [
externals({
deps: false, // Dependencies will be bundled in
}),
],
sourceMap: true,
},
],
},
];
I have also tried to do the same thing with something like
import { nodeResolve } from '#rollup/plugin-node-resolve';
export default {
input: 'src/index.js',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [nodeResolve()]
};
but to no avail it never bundles up the node packages into the build file and always gives the error :
...
three/examples/jsm/lines/Line2.js (guessing 'Line2_js')
three/examples/jsm/lines/LineMaterial.js (guessing 'LineMaterial_js')
three/examples/jsm/lines/LineGeometry.js (guessing 'LineGeometry_js')
three/examples/jsm/controls/OrbitControls (guessing 'OrbitControls')
#deck.gl/core (guessing 'core')
#deck.gl/layers (guessing 'layers')
(!) Unresolved dependencies

Vue 3 on Vite.js with Eslint — Unable to resolve path to module eslint(import/no-unresolved)

I use Vue 3 on Vite.js with Eslint + Airbnb config. Airbnb config has a rule eslint(import/no-unresolved), which is good, but Eslint doesn't know how to resolve alias path.
I want to use aliases for paths — example:
import TableComponent from '#/components/table/TableComponent.vue'˙
Environment is in plain JavaScript.
I managed to set up my vite.config.js so that the app can resolve paths like this:
import path from 'path';
import { defineConfig } from 'vite';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: [{
find: "#", replacement: path.resolve(__dirname, 'src')
},],
},
});
Vue app works like that and resolves the import path correctly, but Eslint keeps reporting the error: Unable to resolve path to module eslint(import/no-unresolved)
How and where can I tell Eslint how to resolve aliases?
I have tried:
install eslint-plugin-import eslint-import-resolver-alias --save-dev
// .eslintrc.js
// ...
extends: [
'eslint:recommended',
'plugin:import/recommended',
'airbnb-base',
'plugin:vue/vue3-strongly-recommended',
],
settings: {
'import/resolver': {
alias: {
map: [
['#', 'src'],
],
},
},
},
But that doesn't work.
EDIT:
Solved the issue, see the accepted answer if you're using plain JavaScript like I do.
If you're using TypeScript, see if Seyd's answer can help you.
this solves the issue in my TypeScript project.
npm install eslint-import-resolver-typescript
After eslint-import-resolver-typescript installation
{
// other configuration are omitted for brevity
settings: {
"import/resolver": {
typescript: {} // this loads <rootdir>/tsconfig.json to eslint
},
},
}
should be added to .eslintrc.js.
my tsconfig.json (remove unwanted settings)
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": false,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"types": ["vite/client", "node"],
"baseUrl": ".",
"paths": {
"#/*": ["src/*"]
},
"allowJs": true
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules"]
}
Check the discussion here:
In case someone runs into this problem, this works in my case*:
settings: {
'import/resolver': {
alias: {
map: [
['#', './src'],
],
},
},
},
*In my case, Vue's root is 'src' directory, while Eslint's is one level higher, so it needs the './src' path.
Huge thanks to #https://github.com/aladdin-add for the answer through the github question!
I had the same problem, and even I fixed the src path it still hat the issue. It did not work until I added extensions:
"settings": {
"import/resolver": {
"alias": {
"map": [
["#", "./src"]
],
"extensions": [".js",".jsx"] <--- HERE
}
}
},
1. Use & export aliases in vite.config.js
// vite.config.js
import { resolve } from 'path';
import { defineConfig } from 'vite';
export const aliases = {
'#': resolve(__dirname, './src'),
'#u': resolve(__dirname, './src/utils'),
};
export default () => defineConfig({
// ...
resolve: {
alias: aliases,
},
})
2. Create .eslintrc with ES Modules support. (Thanks to Morgan's answer)
2.1 npm i esm -D
2.2 Create sibling to .eslintrc.js — .eslintrc.esm.js.
2.3 Put your your ESLint config into .eslintrc.esm.js.
// .eslintrc.esm.js
export default {
root: true,
extends: ['#vue/airbnb', 'plugin:vue/recommended'],
// ...
}
2.4 Inside .eslintrc.js include this code:
const _require = require('esm')(module)
module.exports = _require('./.eslintrc.esm.js').default
3. Import, map & use aliases from vite.config.js in .eslintrc.esm.js
3.1 npm i eslint-import-resolver-alias -D
3.2 Inside .eslintrc.esm.js include following code:
// .eslintrc.esm.js
import { aliases } from './vite.config';
const mappedAliases = Object.entries(aliases).map((entry) => entry); // [[alias, path], [alias, path], ...]
export default {
// ...
settings: {
'import/resolver': {
alias: {
map: mappedAliases,
},
},
},
}
I can't for the life of me get this to work, I've tried everything above. Is there something else wrong with my file?
// .eslintrc.cjs
/* eslint-env node */
require("#rushstack/eslint-patch/modern-module-resolution");
module.exports = {
root: true,
extends: [
"airbnb",
"plugin:vue/vue3-essential",
"eslint:recommended",
"#vue/eslint-config-prettier",
],
parserOptions: {
ecmaVersion: "latest",
},
// Using the accepted answer
settings: {
"import/resolver": {
alias: {
map: [["#", "./src"]],
},
},
},
};
** UPDATE **
The only way I was able to get this to work was using this: eslint-config-airbnb link here, the readme was particularly helpful.
npm add --dev #vue/eslint-config-airbnb #rushstack/eslint-patch
My .eslintrc.js is now:
/* eslint-env node */
require("#rushstack/eslint-patch/modern-module-resolution");
const path = require("node:path");
const createAliasSetting = require("#vue/eslint-config-airbnb/createAliasSetting");
module.exports = {
root: true,
extends: [
"plugin:vue/vue3-essential",
"#vue/eslint-config-airbnb", // <-- added
"eslint:recommended",
"#vue/eslint-config-prettier",
],
parserOptions: {
ecmaVersion: "latest",
},
rules: {
"import/no-unresolved": "error",
},
settings: {
...createAliasSetting({
"#": `${path.resolve(__dirname, "./src")}`,
}),
},
};
Huzzah!
In the README.md of eslint-plugin-import it is said:
Currently Node and webpack resolution have been implemented, but the resolvers are just npm packages, so third party packages are supported (and encouraged!).
Here you can see the list of the third party resolvers.
One that worked for me was this: eslint-import-resolver-custom-alias, and this is how I used it:
settings:
import/resolver:
eslint-import-resolver-custom-alias:
alias:
'#': './app/javascript'
extensions:
- '.js'
- '.vue'
For me the # had been set as an alias for app/javascript inside vite.config.ts, you should change this based on your project configurations.
in .eslintrc.js add
settings: {
'import/resolver': {
alias: {
map: [['#', './src/']],
extensions: ['.js', '.vue'],
},
},
},

External JavaScript dependency with Bower

I have a nearly-vanilla Phoenix setup in which I want to use select2[1]. I have bootstrap and jquery configured by means of bower. The front-end is bootstrap 4 and it all works great, so that's covered. See my bower config below.
The steps I tried are the following.
I have created a minimal working example in HTML from the website of select2, and included the js and css via a CDN. This all worked.
I have installed select2 via npm using npm install --save select2.
I have verified that the select2 data is present in my http://localhost:8000/js/app.js.
I have added the script needed to execute select2 on the option list (see below). I have added this below my import of app.js.
When I navigate to the page I have the minimal working example on (the homepage), I see this error in the console:
jQuery.Deferred exception: $(...).select2 is not a function #http://0.0.0.0:4000/:85:9
mightThrow#http://0.0.0.0:4000/js/app.js:7638:21
resolve/</process<#http://0.0.0.0:4000/js/app.js:7706:12
undefined jquery.js:3822
[Show/hide message details.] TypeError: $(...).select2 is not a function[Learn More]
I admit, I have no clue how this all works, as my knowledge is all focussed on backend related tasks. The entire codebase is on github as well [2].
Any help would be appreciated.
Relevant part of app.html.eex
<script src="<%= static_path(#conn, "/js/app.js") %>"></script>
<script>
$(document).ready(function() {
$('.js-example-basic-single').select2();
});
</script>
Html added to layout.html.eex
<select class="js-example-basic-single" name="state">
<option value="AL">Alabama</option>
<option value="WY">Wyoming</option>
</select>
brunch-config.js
exports.config = {
// See http://brunch.io/#documentation for docs.
files: {
javascripts: {
joinTo: "js/app.js"
},
stylesheets: {
joinTo: "css/app.css",
order: {
after: ["css/app.css"] // concat app.css last
}
},
templates: {
joinTo: "js/app.js"
}
},
conventions: {
assets: /^(static)/
},
// Phoenix paths configuration
paths: {
// Dependencies and current project directories to watch
watched: ["static", "css", "js", "vendor", "scss", "fonts"],
// Where to compile files to
public: "../priv/static"
},
// Configure your plugins
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
ignore: [/vendor/]
},
sass: {
native: true,
options: {
includePaths: ["node_modules/bootstrap/scss", "node_modules/font-awesome/scss"], // Tell sass-brunch where to look for files to #import
precision: 8 // Minimum precision required by bootstrap-sass
}
},
copycat: {
"fonts" : ["static/fonts", "node_modules/font-awesome/fonts"],
verbose : false, //shows each file that is copied to the destination directory
onlyChanged: true //only copy a file if it's modified time has changed (only effective when using brunch watch)
}
},
modules: {
autoRequire: {
"js/app.js": ["js/app"]
}
},
npm: {
enabled: true,
globals: {
select2: 'select2',
$: 'jquery',
jQuery: 'jquery',
Tether: 'tether',
Popper: "popper.js",
bootstrap: 'bootstrap'
}
}
};
[1] https://select2.org/
[2] https://github.com/m1dnight/gymlog/tree/frontend_crap

Using requirejs and trying to optimize javascript into a vendor file and an app file

I'm working on a project using requirejs and I'm trying to optimize my javascript into two files: vendor libraries and app code. Unfortunately, I can't seem to get it to work.
Folder structure:
backbone_components/
app/
less/
js/
component1/
component2/
layouts/
dashboard/
about/
lib/
config.js
main.js
index.html
dist/
Gruntfile.js
config.js:
require.config({
baseUrl: '../js/',
paths: {
jquery: '../../bower_components/jquery/dist/jquery',
underscore: '../../bower_components/lodash/dist/lodash',
backbone: '../../bower_components/backbone/backbone',
text: '../../bower_components/requirejs-text/text'
},
enforeceDefine: true
});
define(['backbone', 'main'], function(Backbone, app) {
});
Gruntfile.js:
requirejs: {
options: {
dir: 'dist/js/',
mainConfigFile: 'app/js/config.js',
optimize: 'none',
normalizeDirDefines: 'all',
skipDirOptimize: true
},
dist: {
options: {
modules: [
{
name: 'vendor',
include: ['jquery', 'underscore', 'backbone', 'text'],
},
{
name: 'app',
exclude: ['vendor']
}
]
}
}
});
When I run grunt, I get the following error: "Error: Error: ERROR: module path does not exist: /path/to/project/app/js/app/js/vendor.js for module named: vendor."
Why is it looking for "vendor" when it doesn't exist yet?
I take it that you have no module named vendor in the source you want to optimize. If this is correct, then the error you are getting is because r.js is looking for a module named vendor. You have to tell it to create it with the create option:
modules: [
{
name: 'vendor',
create: true, // <--- Add this option!
include: ['jquery', 'underscore', 'backbone', 'text']
},
{
name: 'app',
exclude: ['vendor']
}
]
Without the option r.js understands you to be effectively saying "take the vendor module and include with it jquery, etc." With the option, you are telling it to create vendor from scratch.
The create option is documented in this file.

How to optimize ember-data with r.js

I recently switched to ember-data#canary, then r.js started failing.
[Error: Error: ENOENT, no such file or directory
'/scripts/lib/ember-data/ember-data/core.js'
In module tree:
app/main
app/app
ember-data
at Object.fs.openSync (fs.js:427:18)
]
This is the build configuration file
`File: build.js`
var config = {
mainConfigFile: '/scripts/common.js',
}
This is the requirejs configuration file
requirejs.config({
paths: {
ember: 'ember/ember',
jquery: 'jquery/dist/jquery',
requirejs: 'requirejs/require',
handlebars: 'handlebars/handlebars',
'ember-data': 'ember-data/ember-data',
},
shim: {
ember: {
deps: [
'handlebars',
'jquery'
],
exports: 'Ember'
},
'ember-data': {
deps: [
'ember'
],
exports: 'DS'
},
}
});
This is how i use ember-data:
define(['ember', 'ember-data'], function(Ember, DS) {
});
You can see the ember-data canary builds here.
This bug have meet from ember-data 1.0.0-beta.9, because in this version has been updated function require in sources. You can revert to beta.8 or try to fix this problem with plugin derequire (grunt-derequire, gulp-derequire).
I've fix it with this task:
gulp.task('build-derequire', function() {
return gulp.src([paths.src.common + '/bower_components/**/ember-data*.js'])
.pipe($.derequire([
{
from: 'require',
to: '_dereq_'
},
{
from: 'define',
to: '_defi_'
}
]))
.pipe(gulp.dest(paths.dev_dist + '/scripts/lib'));
});

Categories

Resources