$ 未在 Rails 应用程序中使用 Webpack 2 的 .js.erb 视图中定义

Posted

技术标签:

【中文标题】$ 未在 Rails 应用程序中使用 Webpack 2 的 .js.erb 视图中定义【英文标题】:$ is not defined within a .js.erb view using Webpack 2 in Rails app 【发布时间】:2017-10-03 19:58:07 【问题描述】:

我正在 Rails 4 应用程序中从资产管道迁移到 Webpack 2。除了 .js.erb 视图中使用 jQuery 的 JS 代码之外,一切似乎都运行良好。

webpack.config.js的内容如下(指纹和压缩省略代码):

const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const jsOutputTemplate = 'javascripts/[name].js'
const cssOutputTemplate = 'stylesheets/[name].css'

module.exports = 
  context: path.join(__dirname, '/app/assets'),
  entry: 
    application: ['./javascripts/application.js', './stylesheets/application.scss']
  ,
  output: 
    path: path.join(__dirname, '/public'),
    filename: jsOutputTemplate
  ,
  module: 
    rules: [
      
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: 
          presets: ['es2015']
        
      ,
      
        test: /\.css$/,
        use: ExtractTextPlugin.extract(['css-loader', 'resolve-url-loader'])
      ,
      
        test: /\.s(a|c)ss$/,
        use: ExtractTextPlugin.extract(['css-loader', 'resolve-url-loader', 'sass-loader?sourceMap'])
      ,
      
        test: /\.(woff2?|svg)$/,
        use: 'url-loader?limit=10000&name=/fonts/[name].[ext]'
      ,
      
        test: /\.(ttf|eot)$/,
        use: 'file-loader?name=/fonts/[name].[ext]'
      ,
      
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: 'url-loader?limit=10000&name=/images/[name].[ext]'
      ,
      
        test: /\.erb$/,
        enforce: 'pre',
        use: 'rails-erb-loader'
      
    ]
  ,
  plugins: [
    new ExtractTextPlugin(
      filename: cssOutputTemplate,
      allChunks: true
    ),
    new webpack.ProvidePlugin(
      $: 'jquery',
      '$': 'jquery',
      'window.$': 'jquery',
      jQuery: 'jquery',
      'jQuery': 'jquery',
      'window.jQuery': 'jquery',
      jquery: 'jquery',
      'jquery': 'jquery',
      'window.jquery': 'jquery'
    )
  ]

jQuery 库(和其他相关)在 app/assets/javascripts/application.js 中是必需的,如下所示:

require('jquery');
require('jquery-ui');
require('jquery-ujs');
require('jquery-datepicker');

如您所见,我已将 rails-erb-loader 用于 .erb 文件,但它并没有像我预期的那样工作。当 .js.erb 文件被渲染时,我总是在控制台中收到下一个错误:

Uncaught ReferenceError: $ is not defined

这个文件里面的代码没什么花哨的,只是包含了一些调用jQuery的$函数的JS:

let $messagesArea = $('#js-attachments-messages');

但是,在控制台中 $ 是在我打印它时定义的,即使在 .js.erb 的开头使用 调试器

function $(selector, [startNode])  [Command Line API]  

我已经在 webpack.config.js 的插件部分中包含了我想出的所有可能的组合来定义 jQuery:

new webpack.ProvidePlugin(
  $: 'jquery',
  '$': 'jquery',
  'window.$': 'jquery',
  jQuery: 'jquery',
  'jQuery': 'jquery',
  'window.jQuery': 'jquery',
  jquery: 'jquery',
  'jquery': 'jquery',
  'window.jquery': 'jquery'
)

有没有我没有考虑到的配置?

如能解决此问题,我们将不胜感激。

更新

package.json的内容如下:


  "devDependencies": 
    "babel-core": "^6.24.1",
    "babel-loader": "^7.0.0",
    "babel-polyfill": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "compression-webpack-plugin": "^0.4.0",
    "css-loader": "^0.28.0",
    "expose-loader": "^0.7.3",
    "extract-text-webpack-plugin": "^2.1.0",
    "file-loader": "^0.11.1",
    "imports-loader": "^0.7.1",
    "node-sass": "^4.5.2",
    "rails-erb-loader": "^5.0.0",
    "resolve-url-loader": "^2.0.2",
    "sass-loader": "^6.0.3",
    "style-loader": "^0.16.1",
    "url-loader": "^0.5.8",
    "webpack": "^2.4.1",
    "webpack-dev-server": "^2.4.4"
  ,
  "dependencies": 
    // ...
    "jquery": "^3.2.1",
    "jquery-datepicker": "^1.11.5",
    "jquery-ui": "^1.12.1",
    "jquery-ujs": "^1.2.2",
    // ...
  

更新 2

我上传了一个示例应用程序,它重现了尝试删除资源然后使用 jQuery 从页面中删除它的错误。

Sample app

【问题讨论】:

试试这个***.com/a/28989476/1817690和github.com/webpack/webpack/issues/4258 你有没有尝试在文件中声明类似 declare var $ as any 这些选项都不起作用。我上传了一个重现错误的示例应用程序。该链接包含在帖子中。 @backpackerhh ,你解决了这个问题吗?因为我面临同样的问题? @MubashirKamranSWEngineer 我发现解决此错误的唯一方法是在.js.erb 文件中使用文件的显式内联渲染:<%= render file: 'node_modules/jquery/dist/jquery.min.js' %>。我知道这不是一个理想的解决方案,但它确实有效! 【参考方案1】:

我最近遇到了类似的错误,因为 Webpack 中所需的 jQuery 未在我的应用程序的 view 文件夹中公开,因此在我的 js.erb 文件中不可见。 这通过在 app/javascript/packs/application.js 中全局公开 jQuery 添加以下 2 行来解决:

从'jquery'导入$;

global.$ = jQuery;

【讨论】:

谢谢,这不仅有助于解决类似问题,而且解释了原因。 谢谢!我对 js.erb 有完全相同的问题。【参考方案2】:

我认为在上面链接的示例应用中使用expose-loader 就足够了,as I proposed in a pull request。

总结一下,

添加expose-loader 将 jQuery 公开给全局对象

module: 
  rules: [
    
      test: require.resolve('jquery'),
      use: [
        loader: 'expose-loader',
        options: '$'
      ]
    
  ]

【讨论】:

以上是关于$ 未在 Rails 应用程序中使用 Webpack 2 的 .js.erb 视图中定义的主要内容,如果未能解决你的问题,请参考以下文章

凭证文件未在 Amazon Linux 上读取 Rails 6.1

Rails/Webpacker 未在生产中加载 Vue 样式

尝试 rake db:migrate 时未在 rails 项目中选择数据库

Rails 4图像未在heroku上加载

未在 Rails 应用程序中应用 CSS 更改

Rack-cors 未在 swagger-ui_rails 的生产环境中显示标题