Webpacker, babel, uglifyjs-webpack-plugin - not transforming arrow functions, but only in Vue files - ruby-on-rails

Running webpacker 3.5.5 (both the gem and package). This is mostly working, but in IE11 the app is broken because arrow functions do not appear to be transformed. However, inspecting the minified code it seems like the only place arrow functions aren't transformed are inside my vue components.
I think this is because my babel class properties plugin is not applying to my Vue loader somehow, but I haven't been able to come up with a solution.
Here's my .babelrc
{
"presets": [
[
"env",
{
"modules": false,
"targets": {
"browsers": [
"> 1%",
"IE 11"
],
"uglify": true
},
"useBuiltIns": true
}
]
],
"plugins": [
"syntax-dynamic-import",
"transform-object-rest-spread",
[
"transform-class-properties",
{
"spec": true
}
]
],
"env": {
"test": {
"presets": ["es2015"]
}
}
}
And here's the entirety of my environment.js file that modifies the webpack environment that webpacker ships with (vue loader is at the bottom).
const { environment } = require('#rails/webpacker');
environment.loaders.append('expose', {
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: 'jQuery'
}]
});
const webpack = require('webpack');
// append some global plugins
environment.plugins.append('Provide', new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
axios: 'axios',
moment: 'moment-timezone',
_: 'lodash'
}));
// Necesary configuration for vue-loader v15
const VueLoaderPlugin = require('vue-loader/lib/plugin');
environment.plugins.append(
'VueLoaderPlugin',
new VueLoaderPlugin()
);
environment.loaders.append('vue', {
test: /\.vue$/,
loader: 'vue-loader'
});
module.exports = environment;
Edit for more info: Here is the entry point to my pack called 'wrestling'
import 'babel-polyfill';
import 'wrestling';
Then in wrestling.js...
import './styles/wrestling'
import Rails from 'rails-ujs'
Rails.start();
import wrestlingSetup from './wrestlingSetup'
wrestlingSetup();
WrestlingSetup contains the actual references to the vue files. I've cut down the file to show what a single vue import looks like within the file. All the rest are essentially the same.
import Vue from 'vue/dist/vue.esm'
// Redacted a bunch of imports, but they all look like this oen
import WrestlerCreate from './vue/wrestler_create.vue'
export default function() {
document.addEventListener('DOMContentLoaded', () => {
axiosSetup();
const app = new Vue({
el: '#app',
components: {
// Other vue components here that I've removed for simplicity
WrestlerCreate,
}
})
});
}
Here's an actual example of the Vue component
<template>
<div role="form">
<!-- other form elements -->
</div>
</template>
<script>
export default {
name: 'wrestler-create',
props: [
],
// This does not get transformed by babel
data() {
return {
loading: false,
error: false,
errorMessage: "Error, please try again later or contact support.",
first_name: '',
last_name: '',
weight_class: '',
academic_class: ''
}
},
methods: {
// removed for simplicity
}
}
</script>

For clarify sake:
Please use function() for data. I find function() gives me less trouble than arrow functions.
export default {
data: function() {
return {
message: "Hello something!",
secondMessage: "Hello world!"
};
}
}
If you really wish to use arrow function, you can write:
export default {
data: () => {
return {
message: "Hello something!",
secondMessage: "Hello world!"
};
}
}

Related

Import image with vanilla-extract and esbuild

I have a problem with images importing using vanilla-extract and esbuild
my build file:
const { build } = require("esbuild");
const { vanillaExtractPlugin } = require("#vanilla-extract/esbuild-plugin");
(async () => {
await build({
entryPoints: ["src/entry.tsx"],
bundle: true,
minify: true,
sourcemap: true,
platform: "browser",
outfile: "dist/entry.js",
plugins: [vanillaExtractPlugin()],
loader: {
".svg": "file",
},
});
})();
my entry.tsx
import { someStyle } from "./style.css";
console.log(someStyle);
When i importing my image in "css" way
import { style } from "#vanilla-extract/css";
export const someStyle = style({
backgroundColor: "url(./x.svg)",
});
The compiler return error
Could not resolve "./x.svg" (the plugin "vanilla-extract" didn't set a resolve directory)`
If i am trying to import x.svg using the typescript import
import { style } from "#vanilla-extract/css";
import svg from "./x.svg";
export const someStyle = style({
backgroundColor: `url(${svg})`,
});
I have other error
src/style.css.ts:5:16: error: No loader is configured for ".svg" files: src/x.svg'
Is it possible to import images with vanilla-extract modules without marking them as external?
It not working now. Workaround is to use babel
import babel from 'esbuild-plugin-babel';
plugins: [
babel({
filter: /.*.css.ts/,
config: {
presets: ['#babel/preset-typescript'],
plugins: ['#vanilla-extract/babel-plugin'],
},
}),
],

No such file or directory, when using Vite and Antd Pro Layout

No such file or directory, when using Vite and Antd Pro Layout
This is file vite.config.ts:
import { defineConfig } from 'vite';
import reactRefresh from '#vitejs/plugin-react-refresh';
import path from 'path';
import vitePluginImp from 'vite-plugin-imp';
export default defineConfig({
plugins: [
reactRefresh(),
vitePluginImp({
libList: [
{
libName: 'antd',
style: (name) => {
return `antd/lib/${name}/style/index.less`;
},
},
],
}),
],
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
modifyVars: {
...{
'primary-color': '#1DA57A',
'link-color': '#1DA57A',
'border-radius-base': '2px',
},
},
},
},
},
resolve: {
alias: [
{
find: /^~/,
replacement: path.resolve(__dirname, 'src'),
},
],
},
optimizeDeps: {
include: ['#ant-design/icons'],
},
});
This is my config to using antd, antd-pro-layout with vite.
But I received the error:
[vite] Internal server error: ENOENT: no such file or directory, open
'/Users/tranthaison/DEV/vite2-react-ts/srcantd/es/style/themes/default.less'
Can someone help me to fix it?
I had some problems when using React + Antd in Vite.
Thanks for #theprimone for the answer. But the answer is incomplete. I will complete the answer here.
First time, add additional config to Less Preprocessor:
Add this config to your vite.config.js file:
{
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
},
},
}
Second, setting module aliases to fix Less #import problem:
Again, add the following config into your vite.config.js file:
{
resolve: {
alias: [
{ find: /^~/, replacement: "" },
],
},
}
Last, install vite-plugin-imp plugin to solve Antd ES problem:
Install the vite-plugin-imp dependencies:
pnpm add -D vite-plugin-imp
# or
npm i -D vite-plugin-imp
then, setup the plugin in your vite.config.js file:
{
plugins: [
// React plugin here
vitePluginImp({
libList: [
{
libName: "antd",
style: (name) => `antd/es/${name}/style`,
},
],
}),
];
}
The final configuration in vite.config.js file will look like this:
import { defineConfig } from "vite";
import reactRefresh from '#vitejs/plugin-react-refresh';
import vitePluginImp from "vite-plugin-imp";
export default defineConfig({
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
},
},
resolve: {
alias: [
{ find: /^~/, replacement: "" },
],
},
plugins: [
reactRefresh(),
vitePluginImp({
libList: [
{
libName: "antd",
style: (name) => `antd/es/${name}/style`,
},
],
}),
],
});
Also work with #preact/preset-vite.
Ref:
https://github.com/theprimone/vite-react
https://github.com/ant-design/ant-design/issues/7850
https://github.com/vitejs/vite/issues/2185#issuecomment-784637827
Try to import antd styles like this:
vitePluginImp({
libList: [
{
libName: 'antd',
style: (name) => `antd/es/${name}/style`,
},
],
}),
More usage of Vite + React + Ant Design or other UI Library, this repo theprimone/vite-react might give you more or less inspiration.

Module parse failed: Unexpected character '�' (1:0) You may need an appropriate loader to handle this file type when added jpeg or mp3

I am working on a rails app with vue on front end. I am getting this error when try to add any image or mp3 file to my project. Please help me resolve this issue. Below is my environment.js file.
I am using webpack version
#rails/webpacker": "^3.2.0"
Below is the home.vue file which is causing the issue. When I try to add this mp3 file I get that error.
home.vue
<template>
<div>
<v-layout row wrap>
<v-flex xs12 sm4 md4 class="hidden-xs-only">
<p>
<!-- <a :href="require('images/company-overview.mp3')" target="_blank" title="Read Article">
<img src="../../images/company-logo.png"/>
</a> -->
</p>
</v-flex>
</v-layout>
</div>
</div>
</template>
<script>
export default {
};
</script>
environment.js
const { environment } = require('#rails/webpacker')
const coffee = require('./loaders/coffee');
const vue = require('./loaders/vue')
environment.loaders.append('coffee', coffee);
environment.loaders.append('vue', vue)
environment.loaders.append('jshint', {
test: /\.js$/, // include .js files
enforce: "pre", // preload the jshint loader
exclude: /node_modules/, // exclude any and all files in the node_modules folder
use: [{
loader: "jshint-loader"
}]
});
environment.loaders.append('signature_pad', {
test: /\.js?$/,
include: [/node_modules\/signature_pad/],
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: [['env', { 'modules': false, 'targets': { 'node': 4 } }]]
}
}],
});
environment.loaders.append('sass', {
test: /\.(sass|scss)$/,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
{
loader: 'sass-loader',
options: {
// Prefer `dart-sass`
implementation: require('sass'),
},
},
],
});
const resolver = {
resolve: {
alias: {
'vue$': 'vue/dist/vue.js'
}
}
};
environment.config.merge(resolver);
module.exports = environment;

Typescript equivalent of inline JavaScript

This may be self-evident but I'm not finding any example that informs what I'm trying to do (maybe I'm just doing it wrong). I'm adding Vue to an existing ASP.NET Core MVC application and adding the JavaScript statements directly to the page works but when I try to migrate to a TypeScript file nothing happens.
The JavaScript is:
new Vue({
el: "#productPage",
data: {
isLoading: true
},
methods: {
},
mounted () {
console.log("mounted()");
this.isLoading = false;
}
});
This works as expected. Migrating the code to a TypeScript file productPage.ts:
import Vue from 'vue';
new Vue({
el: "#productPage",
data: {
isLoading: true
},
methods: {
},
mounted () {
console.log("mounted()");
this.isLoading = false;
}
});
Which generates:
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "vue"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var vue_1 = require("vue");
var HonestyBox;
(function (HonestyBox) {
new vue_1.default({
el: "#productPage",
data: {
isLoading: true
},
methods: {},
mounted: function () {
console.log("Mounted !!!!");
this.isLoading = false;
}
});
})(HonestyBox || (HonestyBox = {}));
});
//# sourceMappingURL=productPage.js.map
And including the generated javascript file productPage.js:
<script src="~/js/productPage.js"></script>
This does nothing. Stepping through the debugger neither of the conditions in function(factory) are satisfied. The console tells me You are running Vue in development mode. but the included JavaScript fails to run. The tsconfig.json used to generate the JavaScript file:
{
"compileOnSave": true,
"compilerOptions": {
"module": "umd",
"moduleResolution": "node",
"noImplicitAny": false,
"noEmitOnError": true,
"removeComments": true,
"sourceMap": true,
"target": "es5",
"outDir": "wwwroot/js"
},
"include": [
"Typescript/**/*"
],
"exclude": [
"node_modules",
"wwwroot"
]
}
Using "module": "commonjs" results in ReferenceError: exports is not defined. I was hoping to avoid having to use Browserify or Webpack.
If I understand you correctly you add Vue in a separate script tag before your productPage.js.
This means that you can't import Vue in your TypeScript file, but you need to declare Vue so the module just assumes that Vue has been loaded already (outside of your TS module).
declare const Vue; // this replaces your Vue import statement
If you want to add a bundler later on, you need to remove your script tag which loads Vue and only go the modular approach:
Vue needs to be imported with an import statement so the bundler knows that he has to include all of Vue.
You will then have one single JS file (or if your bundler splits it: multiple JS files).

use jquery-ui with webpack having a particular file structure

I would like you to help/suggest the best way to use datepicker from jquery-ui having the following file structure:
-single_pages
-admin
-admin.js
-webpack.config.js
-common
-DatesFilter
-DatesFilter.js
-node_modules
-package.json
I already installed jquery-ui
My webpack.config.js file is:
var path = require('path');
var webpack = require("webpack");
module.exports = {
resolve: {
alias: {
'jquery': require.resolve('jquery'),
},
root: [
path.resolve(__dirname, './../admin'),
path.resolve(__dirname, './../common')
],
extensions: ['', '.js'],
fallback: path.resolve(__dirname, './../node_modules')
},
resolveLoader: {
fallback: path.resolve(__dirname, './../node_modules')
},
entry: './index.js',
output: {
filename: 'bundle.js',
publicPath: "/"
},
externals: {
// require("jquery") is external and available
// on the global var jQuery
"jquery": "jQuery"
},
plugins: [
new webpack.ProvidePlugin({
"$":"jquery",
"jQuery":"jquery",
"window.jQuery":"jquery"
})
],
module: {
loaders: [
{
test: /\.js$/,
include: [
path.resolve(__dirname, './')
],
loader: "babel-loader"
},
{
test: /\.js$/,
include: path.resolve(__dirname, './../common'),
babelrc: false,
loader: require.resolve('babel-loader'),
query: { // load the same presets as in the .babelrc file, but in a way that resolves in the parent directory
presets: [require.resolve('babel-preset-es2015'), require.resolve('babel-preset-react'),
require.resolve('babel-preset-stage-0')]
}
}
]
}
};
I'm using React.js.
I import DatesFilter.js inside admin.js. I get to see the component. The problem comes when I want to use the datepicker.
DatesFilter.js uses datepicker from jquery-ui
I'm using: import { datepicker } from 'jquery-ui' inside DatesFilter.js but it keeps saying TypeError: $(...).datepicker is not a function
What can I do?
Thank you
Try importing just the module, see this link jquery-ui-and-webpack-how-to-manage-it-into-module
in your case you would import "jquery-ui/ui/widgets/datepicker"

Resources