Loading jEditable library in Webpack - bower

I tried to include jQuery plugin Jeditable as a webpack module from bower. I use bower-webpack-plugin to include some libraries, but it doesn't work in this case.
Edit: I use this webpack config.
webpack.config.js
const BowerWebpackPlugin = require("bower-webpack-plugin");
module.exports = {
entry: './src/script/index.jsx',
output: {
filename: 'bundle.js',
publicPath: 'http://localhost:8090/assets'
},
devtool: 'evil-source-map',
module: {
loaders: [
{
test: /\.js[x]?$/,
loaders: ['react-hot', 'jsx', 'babel'],
exclude: /node_modules/
},
{
test: /\.scss$/,
loaders: [ 'style', 'css?sourceMap', 'sass?sourceMap' ]
}
]
},
plugins: [
new BowerWebpackPlugin()
],
externals: {
'react': 'React'
},
resolve: {
extensions: ['', '.js', '.jsx']
}
}
bower.json
{
"name": "Won",
"version": "0.0.1",
"description": "Internal app",
"main": "index.js",
"authors": [
"and"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"devDependencies": {
"jquery": "~2.1.4",
"babel-polyfill": "~0.0.1",
"bootstrap": "~3.3.5",
"col-resizable": "*",
"datatables": "~1.10.8",
"immutable": "~3.7.4",
"jeditable": "~1.7.3",
"jquery-resizable-columns": "~0.2.3",
"jquery-ui": "~1.11.4",
"kefir": "~2.8.0",
"lodash": "~3.10.1"
}
}
At first I get error:
Uncaught TypeError: $(...).find(...).editable is not a function
Then I tried to add Jeditable plugin
var editable = require('jeditable') or
var editable = require('jquery.jeditable')
but i get errors like
Module not found: Error: Cannot resolve module 'jeditable' in ...
Then I tried
var editable = require('../../bower_components/jeditable/jquery.jeditable')
I get error
Uncaught ReferenceError: jQuery is not defined
(anonymous function) # jquery.jeditable.js:494
Then I tried to add Jquery:
var jQuery = require('../../bower_components/jeditable/js/jquery')
var editable = require('../../bower_components/jeditable/jquery.jeditable')
but I get error:
./bower_components/jeditable/js/jquery.js
Module build failed: SyntaxError: /Users/an/Won_webpack_25_08/bower_components/jeditable/js/jquery.js: 'with' in strict mode (2907:13)
2905 | var left = 0, top = 0, elem = this[0], results;
2906 |
> 2907 | if ( elem ) with ( jQuery.browser ) {
| ^
2908 | var absolute = jQuery.css(elem, "position") == "absolute",
2909 | parent = elem.parentNode,
2910 | offsetParent = elem.offsetParent,

When I add window.jQuery = $; it works now

Related

Transpile Turbo/Rails Turbo for IE 11

I have a rails app using Hotwire (Turbo & Stimulus). I'm trying to use webpack and babel to transpile JS for ES5/IE11. Stimulus and Turbo don't support IE11 any more, so I'm also trying to explicitly transpile them and then add required polyfills. My understanding is even if they've already been transpiled, the result should still be valid ES6 that can be transpiled again.
For Stimulus this approach appears to work fine but for Turbo I get
Uncaught TypeError: t.tagName is undefined
ht turbo.es2017-esm.js:1308
My best guess is that this is because Turbo is distributed as UMD modules so my babel config isn't transpiling it correctly. What's the best way to approach this?
browserlist:
"browserslist": {
"production": [
"last 1 version",
"> 1%",
"IE 10"
],
webpack.config.js:
const path = require("path")
const webpack = require("webpack")
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts')
const CopyPlugin = require("copy-webpack-plugin");
const mode = process.env.NODE_ENV === 'development' ? 'development' : 'production'
module.exports = {
mode,
devtool: "source-map",
entry: {
application: [
"./app/frontend/application.js",
]
},
module: {
rules: [
{
test: /\.(js|ts)$/,
include: [
path.resolve(__dirname, 'node_modules/#hotwired/turbo'),
path.resolve(__dirname, 'node_modules/#hotwired/turbo-rails'),
path.resolve(__dirname, 'node_modules/#hotwired/stimulus'),
path.resolve(__dirname, 'node_modules/#stimulus/polyfills'),
path.resolve(__dirname, 'node_modules/#rails/actioncable'),
path.resolve(__dirname, 'app/frontend'),
],
use: ['babel-loader'],
},
{
test: /\.(png|jpe?g|gif|eot|woff|woff2|ttf|svg|ico)$/i,
type: 'asset/resource'
},
{
test: /\.(scss|css)/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
}
],
},
resolve: {
modules: ['node_modules']
},
output: {
filename: "[name].js",
// we must set publicPath to an empty value to override the default of
// auto which doesn't work in IE11
publicPath: '',
path: path.resolve(__dirname, "app/assets/builds"),
},
plugins: [
new RemoveEmptyScriptsPlugin(),
new MiniCssExtractPlugin(),
new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
new CopyPlugin({
patterns: [
{ from: "node_modules/html5shiv/dist/html5shiv.min.js", to: "vendor" },
{ from: "app/frontend/vendor/outerHTML.js", to: "vendor" },
{ from: "app/frontend/vendor/polyfill-output-value.js", to: "vendor" }
],
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery'
})
]
}
babel.config.js
module.exports = function(api) {
var validEnv = ['development', 'test', 'production']
var currentEnv = api.env()
var isDevelopmentEnv = api.env('development')
var isProductionEnv = api.env('production')
var isTestEnv = api.env('test')
if (!validEnv.includes(currentEnv)) {
throw new Error(
'Please specify a valid `NODE_ENV` or ' +
'`BABEL_ENV` environment variables. Valid values are "development", ' +
'"test", and "production". Instead, received: ' +
JSON.stringify(currentEnv) +
'.'
)
}
return {
presets: [
isTestEnv && [
'#babel/preset-env'
],
(isProductionEnv || isDevelopmentEnv) && [
'#babel/preset-env',
{
forceAllTransforms: true,
useBuiltIns: 'entry',
corejs: '3.21.1',
modules: false,
exclude: ['transform-typeof-symbol']
}
]
].filter(Boolean),
plugins: [
'babel-plugin-macros',
'#babel/plugin-syntax-dynamic-import',
isTestEnv && 'babel-plugin-dynamic-import-node',
'#babel/plugin-proposal-class-properties',
'#babel/plugin-proposal-object-rest-spread',
'#babel/plugin-proposal-private-methods',
'#babel/plugin-proposal-private-property-in-object',
'#babel/plugin-transform-regenerator',
'#babel/plugin-transform-runtime',
[
'#babel/plugin-transform-spread',
{
loose: true
}
]
].filter(Boolean)
}
}

Test an .js.erb file with Rails + Webpacker + Jest

I have a Rails 5 app which uses webpacker, with a file app/javascript/packs/components/module_one.js which I'm trying to test with Jest. This file contains an import to an .js.erb file as follows:
// app/javascript/packs/components/module_one.js
import ModuleTwo from './module_two.js.erb'
// ...
module_two.js.erb contains the following:
// app/javascript/packs/components/module_two.js.erb
import ModuleOne from './module_one'
// ...
While running webpack-dev-server everything works as expected, but when I try to run yarn test, it complains with the following error:
FAIL app/javascript/test/module_one.test.js
● Test suite failed to run
/path/to/module_two.js.erb:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import ModuleOne from './module_one'
^^^^^^
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:306:17)
at Object.<anonymous> (app/javascript/packs/components/module_one.js:1:745)
at Object.<anonymous> (app/javascript/test/module_one.test.js:1:124)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 2.545s
Ran all test suites.
error Command failed with exit code 1.
So it seems like the module_two.js.erb file is not being transformed properly from ES6, because when I remove the first line of module_one.js, it doesn't complain anymore.
Here is my current setup:
// .babelrc
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": "> 1%",
"uglify": true
},
"useBuiltIns": true
}]
],
"plugins": [
"syntax-dynamic-import",
["transform-class-properties", { "spec": true }]
],
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
// package.json
{
// ...
"devDependencies": {
"babel-jest": "^21.0.2",
"jest": "^21.0.2",
"regenerator-runtime": "^0.11.0",
"webpack-dev-server": "^2.7.1"
},
"scripts": {
"test": "jest"
},
"jest": {
"roots": [
"<rootDir>/app/javascript/test"
],
"moduleDirectories": [
"<rootDir>/node_modules"
],
"moduleFileExtensions": [
"js",
"jsx",
"erb"
],
"transform": {
"^.+\\.jsx?$": "babel-jest",
"ˆ.+\\.jsx?.erb": "rails-erb-loader"
}
}
}
In case someone else bumps into this.
Your .babelrc seems to be missing "es2015" preset.
Here is well explained about this and other issues configuring JS testing with Rails + Webpacker.

Installing Isotope + packery-mode with Bower

I'm trying to install packery-mode with bower. I have this bower.json:
"dependencies": {
"isotope": "^3.0.4",
"isotope-packery": "^2.0.0"
},
"overrides": {
"isotope": {
"main": [
"./dist/isotope.pkgd.js"
],
"dependencies": {}
},
"isotope-packery": {
"main": [
".packery-mode.pkgd.js"
],
"dependencies": {}
},
}
}
And the isotope init:
var $grid = $('.grid').isotope({
layoutMode: 'packery',
itemSelector: '.post'
});
I get an Uncaught Error: No layout mode: packery in the console. Why? packery-mode is present in the main.js (masonry layout works fine).
There was just a typo: missing slash in overrides.
".packery-mode.pkgd.js"
instead
"./packery-mode.pkgd.js"
Sorry for the noise

React on Rails with server side rendering

I created a site using React on Rails. It works perfectly fine, but I have not noticed that server side rendering is turned off, and I need it for SEO so I decided to turn it on. The thing is that now I get an error like this:
ERROR in SERVER PRERENDERING
Encountered error: "ReferenceError: window is not defined"
My webpack.config.js looks like this:
/* eslint comma-dangle: ["error",
{"functions": "never", "arrays": "only-multiline", "objects":
"only-multiline"} ] */
const webpack = require('webpack');
const path = require('path');
const devBuild = process.env.NODE_ENV !== 'production';
const nodeEnv = devBuild ? 'development' : 'production';
const bundles = [
'./app/bundles/Home/startup/registration'
]
const config = {
entry: [
'es5-shim/es5-shim',
'es5-shim/es5-sham',
'babel-polyfill',
...bundles
],
output: {
filename: 'webpack-bundle.js',
path: '../app/assets/webpack',
},
resolve: {
extensions: ['', '.js', '.jsx'],
alias: {
react: path.resolve('./node_modules/react'),
'react-dom': path.resolve('./node_modules/react-dom'),
},
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(nodeEnv),
},
}),
],
module: {
loaders: [
{
test: require.resolve('react'),
loader: 'imports?shim=es5-shim/es5-shim&sham=es5-shim/es5-sham',
},
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
],
},
};
module.exports = config;
if (devBuild) {
console.log('Webpack dev build for Rails'); // eslint-disable-line no-console
module.exports.devtool = 'eval-source-map';
} else {
config.plugins.push(
new webpack.optimize.DedupePlugin()
);
console.log('Webpack production build for Rails'); // eslint-disable-line no-console
}
What should I do to fix it? I read through one of the realted issues on react_on_rails github but I still do not know.

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