简体   繁体   中英

How do I add jQuery to Mastodon (using Rails 6 and Webpacker 4)?

I'm following this question from 2020 How do I use jQuery in Rails 6.0.3.3? , but I'm not able to add jQuery to Rails 6 and Webpacker 4 in Mastodon https://github.com/mastodon/mastodon However, I am able to add a custom.js file to load my jQuery function; it's the main jQuery library that isn't loading.

In Mastodon:~/live$ I run yarn add jquery and that returns:

yarn add v1.22.19
[1/6] Validating package.json...
[2/6] Resolving packages...
[3/6] Fetching packages...
[4/6] Linking dependencies...
warning Workspaces can only be enabled in private projects.
[5/6] Building fresh packages...
[6/6] Cleaning modules...
warning Workspaces can only be enabled in private projects.
success Saved 1 new dependency.
info Direct dependencies
└─ jquery@3.6.3
info All dependencies
└─ jquery@3.6.3
Done in 24.18s.

I see that jQuery has been added to package.json and yarn.lock .

I added require('jquery') to app/javascript/packs/application.js:

import './public-path';
import loadPolyfills from '../mastodon/load_polyfills';
import { start } from '../mastodon/common';

start();

loadPolyfills().then(async () => {
  const { default: main } = await import('mastodon/main');

  return main();
}).catch(e => {
  console.error(e);
});

require('jquery')
require('packs/custom') // custom.js file I added

But I don't have an environment.js file in the Mastodon site files, and the non-existent environment.js file should include this, as referenced in the linked question:

const { environment } = require("@rails/webpacker");
const webpack = require("webpack");

environment.plugins.append(
  "Provide",
  new webpack.ProvidePlugin({
    $: "jquery/src/jquery",
    jQuery: "jquery/src/jquery",
  })
);

module.exports = environment;

I run

RAILS_ENV=production bundle exec rake tmp:cache:clear
RAILS_ENV=production bundle exec rails assets:generate_static_pages

And then

RAILS_ENV=production bundle exec rails assets:precompile

and that outputs this:

yarn install v1.22.19
[1/6] Validating package.json...
[2/6] Resolving packages...
[3/6] Fetching packages...
[4/6] Linking dependencies...
warning Workspaces can only be enabled in private projects.
[5/6] Building fresh packages...
[6/6] Cleaning modules...
Done in 18.17s.
Everything's up-to-date. Nothing to do

I exit from the root account and run

systemctl restart mastodon-*

I test for jQuery in the console and it's not loading:

在此处输入图像描述

But, the packs/custom.js file is loading, as it contains

console.log("custom js is loaded");

and I see custom js is loaded in the console.

Any ideas? Why is jQuery not loading?

  1. Where is the environment.js file file?

  2. Is the notice warning Workspaces can only be enabled in private projects a serious error?

  3. I have run RAILS_ENV=production bundle exec rails assets:clobber to clear Webpacker and that doesn't help with the missing jQuery library.

Edit 1/25/23:

As per mechnicov's answer, this is the shared.js file in /config/webpack/:

const webpack = require('webpack');
const { basename, dirname, join, relative, resolve } = require('path');
const { sync } = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const AssetsManifestPlugin = require('webpack-assets-manifest');
const extname = require('path-complete-extname');
const { env, settings, themes, output } = require('./configuration');
const rules = require('./rules');
const localePackPaths = require('./generateLocalePacks');

const extensionGlob = `**/*{${settings.extensions.join(',')}}*`;
const entryPath = join(settings.source_path, settings.source_entry_path);
const packPaths = sync(join(entryPath, extensionGlob));

module.exports = {
  entry: Object.assign(
    packPaths.reduce((map, entry) => {
      const localMap = map;
      const namespace = relative(join(entryPath), dirname(entry));
      localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry);
      return localMap;
    }, {}),
    localePackPaths.reduce((map, entry) => {
      const localMap = map;
      localMap[basename(entry, extname(entry, extname(entry)))] = resolve(entry);
      return localMap;
    }, {}),
    Object.keys(themes).reduce((themePaths, name) => {
      themePaths[name] = resolve(join(settings.source_path, themes[name]));
      return themePaths;
    }, {}),
  ),

  output: {
    filename: 'js/[name]-[chunkhash].js',
    chunkFilename: 'js/[name]-[chunkhash].chunk.js',
    hotUpdateChunkFilename: 'js/[id]-[hash].hot-update.js',
    hashFunction: 'sha256',
    path: output.path,
    publicPath: output.publicPath,
  },

  optimization: {
    runtimeChunk: {
      name: 'common',
    },
    splitChunks: {
      cacheGroups: {
        default: false,
        vendors: false,
        common: {
          name: 'common',
          chunks: 'all',
          minChunks: 2,
          minSize: 0,
          test: /^(?!.*[\\\/]node_modules[\\\/]react-intl[\\\/]).+$/,
        },
      },
    },
    occurrenceOrder: true,
  },

  module: {
    rules: Object.keys(rules).map(key => rules[key]),
  },

  plugins: [

    new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }),

    new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
    new webpack.NormalModuleReplacementPlugin(
      /^history\//, (resource) => {
        // temporary fix for https://github.com/ReactTraining/react-router/issues/5576
        // to reduce bundle size
        resource.request = resource.request.replace(/^history/, 'history/es');
      },
    ),
    new MiniCssExtractPlugin({
      filename: 'css/[name]-[contenthash:8].css',
      chunkFilename: 'css/[name]-[contenthash:8].chunk.css',
    }),
    new AssetsManifestPlugin({
      integrity: true,
      integrityHashes: ['sha256'],
      entrypoints: true,
      writeToDisk: true,
      publicPath: true,
    }),
  ],

  resolve: {
    extensions: settings.extensions,
    modules: [
      resolve(settings.source_path),
      'node_modules',
    ],
  },

  resolveLoader: {
    modules: ['node_modules'],
  },

  node: {
    // Called by http-link-header in an API we never use, increases
    // bundle size unnecessarily
    Buffer: false,
  },
};

Firstly add JQuery if don't have it in your package.json

yarn add jquery

As I see Mastodon have webpack

You can use it to install JQuery in the project

For this purpose you can add changes to config/webpack/shared.js or config/webpack/configuration.js

Probably first file is better. Because plugins are installed there and webpack importing is already present

But you can use second file too as you wish

Finally you need to add to plugins array such element

new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM