Including static assets from modules - vue.js

I am trying out the (as of now) latest version of vue-cli and ran into a problem importing static assets. My setup is pretty much a default fresh project with nothing but vuex selected and my first goal was to get a boring template with semantic ui running. This also implies jQuery with semantic ui depending on it.
To this end I added this script section to the main App.vue
<script>
require('~/jquery/dist/jquery.min.js');
require('./semantic/dist/semantic.js');
</script>
..following the URL transformation rules explained here. My (partial) folder structure is:
node_modules
jquery
dist
jquery.min.js
src
semantic
dist
semantic.min.js
Running npm run serve does find semantic but not jquery. Can someone tell me why this proposed method of including static assets does not work in this case?
Edit for clarification: My question is explicitly about this proposed method of importing and the URL transformation rules. For anyone needing some method of getting this to work I am currently using this as a workaround:
<script>
import jQuery from 'jquery';
window.$ = window.jQuery = jQuery;
require('./semantic/dist/semantic.js');
export default {
}
</script>

If you're using webpack. There is another method to includes jQuery as global variable using ProvidePlugin. You can add to your webpack.base.conf.js
module.exports = {
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
jQuery: 'jquery'
})
]
}
If you're using Eslint, you need to add to .eslintrc.js
module.exports = {
globals: {
"$": true,
"jQuery": true
},
...

Related

How can I use obfuscation js with Vue and Nuxt?

I am trying to obfuscate the Nuxt project with javascript-obfuscator. Looking at their documentation it looks like we have to import their plugin in Webpack plugins. But they dont have the documentation for Vue or Nuxt way to do it. I also tried searching on google, but there aren't no relevant examples.
I also want to exclude node_modules from obfuscation.
Nuxt js documentation has something like
import webpack from 'webpack'
export default {
build: {
plugins: [
new webpack.ProvidePlugin({
// global modules
$: 'jquery',
_: 'lodash'
})
]
}
}
And Obsufaction has
var WebpackObfuscator = require('webpack-obfuscator');
// webpack plugins array
plugins: [
new WebpackObfuscator ({
rotateStringArray: true
}, ['excluded_bundle_name.js'])
]
How can i use it with nuxt and also exclude the node_modules folders?

Vue-cli 3 component library to support SSR

I am creating a custom component library that i want to share across multiple domains.
Domains:
Each domain has its own instance of nuxt
Each domain has my-component-lib registered in package.json
Each domain registers the lib as a plugin
//my-component-lib.js
import components from 'my-component-lib'
import Vue from 'vue'
export default ({ store }) => {
Vue.use(components, { store: store })
}
//nuxt.config.js
plugins: [
/*Desired option 1*/ '#/plugins/my-component-lib',
/*Currently using*/ { src: '#/plugins/my-component-lib', ssr: false }
]
my-component-lib:
Setup using vue-cli 3
The library is composed of basic html tags and CSS ex <input ></input>. The styling is important and i would like to keep it together with the component (extract:false) so i can pull individual components out and not worry about importing a css file.
//vue.config.js
module.exports = {
outputDir: 'dist',
lintOnSave: false,
css: {
extract: false
}
}
setup for production using "production": "vue-cli-service build --target lib --name sc components/index.js"
Problems:
Using the desired option, when i run nuxt npm run dev i get a document is not defined in function addStyle (obj /* StyleObjectPart */) {..} within sc.common.js
Using the current option, i get a hydration error(The client-side rendered virtual DOM tree is not matching server-rendered content.) which is fixed if i wrap the components within <no-ssr> tags which i do not want to do.
I want to compile my component library to work with SSR and not have to import a large css file
Change
...
css: {
extract: false
}
...
to true

Migrating Rails from Asset Pipeline to Webpacker: Uncaught ReferenceError: $ is not defined in rails-ujs.js

I am migrating from using the asset pipeline to webpacker in Rails 5.2. My AJAX responses are all causing Uncaught ReferenceError: $ is not defined in rails-ujs.js errors in the browser console.
I have setup my webpacker environment to include jquery.
const { environment } = require('#rails/webpacker');
const webpack = require('webpack');
environment.plugins.append("Provide", new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default']
}));
module.exports = environment;
I have imported rails-ujs and turbolinks in my ../packs/application.js
import Rails from 'rails-ujs'
import 'activestorage'
import 'bootstrap'
...
import Turbolinks from "turbolinks"
Rails.start();
Turbolinks.start();
// Import application specific stuff
import 'application/javascripts'
I then try to add a class when the request is completed. similar to what is shown in the rails guides
https://guides.rubyonrails.org/working_with_javascript_in_rails.html#server-side-concerns
My show.js.erb file looks like this
$("#result").addClass("active")
I get an error
Uncaught ReferenceError: $ is not defined
at <anonymous>:1:1
at processResponse (rails-ujs.js:282)
at rails-ujs.js:195
at XMLHttpRequest.xhr.onreadystatechange (rails-ujs.js:263)
In the meantime, I figured out what I had done wrong. I needed to configure an alias. I found the solution in the docs https://github.com/rails/webpacker/blob/master/docs/webpack.md#configuration
Adding environment.config.set('resolve.alias', {jquery: 'jquery/src/jquery'}); to my /config/webpacker/environment.js did the trick.
const { environment } = require('#rails/webpacker');
const webpack = require('webpack');
environment.plugins.append("Provide", new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default']
}));
environment.config.set('resolve.alias', {jquery: 'jquery/src/jquery'});
module.exports = environment;
Try in app/javascript/packs/application.js:
// jquery
import $ from 'jquery';
global.$ = $;
global.jQuery = $;
Thanks for sharing this. Worked like a charm. To add to your answer, there is a folder named node_modules. Inside that you have jquery/src/jquery.js file. That file is what is being referenced by the line of code above. I am new to JS so pardon my ignorance. What I understand is that this file returns a function called jQuery. When we write
environment.plugins.append("Provide", new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default']
}));
We mess things up. What this basically means is $ = 'jquery' which is not defined at the moment. Next I define jQuery = 'jquery'. So jquery is still undefined. So we have to define an alias by adding that line.
But if I write
environment.plugins.append("Provide", new webpack.ProvidePlugin({
jquery: jQuery,
$: 'jquery',
Popper: ['popper.js', 'default']
}));
Then I don't need to add the code for defining that alias.
Both your solution and this worked for me. As I said I am very new to JS and I cannot say if this is the right solution.

Dedupe CSS in Vue.js development mode

I am working on a Vue.js project that heavily uses single file components. These components have scss styles associated with them.
In production mode the duplicate css that occurs from importing the same component multiple times is filtered out. But in development mode the same scss is imported multiple times.
This leads to slow downs with the chrome debugger when inspecting and modifying the css.
Does anone know a way to dedupe the css/scss attatched to single file components in developlment mode?
Here is my current vue config:
module.exports = {
lintOnSave: false,
configureWebpack: {
resolve: {
alias: require("./aliases.config").webpack
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
_: "lodash"
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
}
Here's how we ended up solving it.
Import only pure SCSS in components (ie. mixins, variables, functions). If a file with CSS is imported in each component the sass loader will NOT dedupe the CSS in development mode.
In your vue config add the following to include you scss variables in every single file component:
module.exports = {
...
css: {
loaderOptions: {
sass: {
data: `
#import "#src/_variables.scss";
`
}
}
},
...
}
Import your global scss in your app entry (main.js or equivalent)
import "bootstrap";
import "#src/global.scss";
In your global.scss file you can import your variables file so that it can also access your scss variables.

JSPM / Aurelia / Bootstrap 4 can't find jQuery

So I have an aurelia setup using jspm. I have install Bootstrap 4 like so:
jspm install npm:bootstrap#4.0.0-alpha.2
Then in main.js I did:
import 'jquery';
import 'bootstrap';
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging();
//Uncomment the line below to enable animation.
//aurelia.use.plugin('aurelia-animator-css');
//if the css animator is enabled, add swap-order="after" to all router-view elements
//Anyone wanting to use HTMLImports to load views, will need to install the following plugin.
//aurelia.use.plugin('aurelia-html-import-template-loader')
aurelia.start().then(() => aurelia.setRoot());
}
I even tried import $ from 'jquery' but when I spin up the aurelia skeleton with BS4 I get:
Uncaught Error: Bootstrap's JavaScript requires jQuery
I can go to the console and do $ and it returns the jquery stuff. I think it is a race condition but not sure how to fix?
EDIT: System.config
System.config({
defaultJSExtensions: true,
transpiler: "none",
paths: {
"*": "dist/*",
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*"
},
meta: {
"bootstrap": {
"deps": [
"jquery"
]
}
},
map: {
Use jspm install bootstrap=github:twbs/bootstrap#4.0.0-alpha.2
There are problems installing bootstrap with jspm from npm: (see here).
See this file for how to import it (from this project).
Update: here is the Pull Request that should fix this.
I ran into this issue recently as well. Try installing jquery 2, instead of jquery 3. Apparently jquery 3 doesn't hang itself off window when it's imported as a module the same as it does in jquery 2. Bootstrap 4 doesn't apparently doesn't request it as a dependency either.
One possible solution is to load jQuery from a CDN in the HEAD section of your index.html:
<script src="https://code.jquery.com/jquery-3.0.0.min.js" integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0=" crossorigin="anonymous"></script>
Taken from https://code.jquery.com. Use a different version of jQuery if you need. This is actually a better deployment strategy IMHO anyway because you will get more concurrent downloads (better parallelism) in the browser by loading libraries from CDNs.