question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Production Build is breaking Vue2-editor

See original GitHub issue

First off this is fantastic! Thank you for your contribution!

In dev (local machine) this is working great. However when I push this into production I am getting errors. I have traced it back to the (FYI im using the default VUE webpack configuration) webpack.optimize.UglifyJsPlugin that is used to build the production code.

If I comment out:

    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      },
      sourceMap: true
    }),

All is right with the world but there is a significant performance hit.

The following are the errors that present themselves:

TypeError: e.isBuffer is not a function
    at d (vue2-editor.js:1)
    at n (vue2-editor.js:1)
    at t.value (vue2-editor.js:1)
    at new t (vue2-editor.js:1)
    at new t (vue2-editor.js:1)
    at a.setQuillElement (vue2-editor.js:1)
    at a.initializeVue2Editor (vue2-editor.js:1)
    at a.mounted (vue2-editor.js:1)
    at Dt (vue.esm.js:2921)
    at Object.insert (vue.esm.js:4158)

AND

vue.esm.js:1741 TypeError: Cannot read property 'innerHTML' of null
    at a.value (vue2-editor.js:1)
    at wa.run (vue.esm.js:3233)
    at Rt (vue.esm.js:2981)
    at Array.<anonymous> (vue.esm.js:1837)
    at at (vue.esm.js:1758)

It is probably worth noting that it attaches to the text area, but any default data from v-model is not persisted into the textarea.

Any help would be appreciated!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:7
  • Comments:13 (2 by maintainers)

github_iconTop GitHub Comments

10reactions
twickstromcommented, Jun 11, 2018

@davidroyer sorry man, great work on this editor. I guess I was over zealous in trying to help others.

It may be worth mentioning that I am using the bubble theme and loading it in the component as such:

import { VueEditor } from 'vue2-editor'
import 'quill/dist/quill.bubble.css'

For the build I am posting the code from the relevant files in the /app/build directory for reference. This has the fix include that I mention above.

webpack.base.conf.js

var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

module.exports = {
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },
  module: {
    rules: [
      {
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        enforce: 'pre',
        include: [resolve('src'), resolve('test')],
        options: {
          formatter: require('eslint-friendly-formatter')
        }
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  }
}

my web pack.prod.conf.js

var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
var UglifyJsPlugin = require('uglifyjs-webpack-plugin')

var env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: false
        }
      },
      sourceMap: true
    }),
    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css')
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: {
        safe: true
      }
    }),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // keep module.id stable when vender modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module, count) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),
    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})

if (config.build.productionGzip) {
  var CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

if (config.build.bundleAnalyzerReport) {
  var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig

The problem was not in your code but it was an underlying compatibility issue between Quill.js and older versions of Uglify.JS

By upgrading to UglifyJS v3 it solved the production build issues.

This is a simple procedure simply cd into your project:

npm i -D uglifyjs-webpack-plugin

Then open: /app/build/webpack.prod.conf.js

Add to the top:

var UglifyJsPlugin = require('uglifyjs-webpack-plugin')

And then look for plugins UglifyJs and change to:

new UglifyJsPlugin({
  uglifyOptions: {
    compress: {
      warnings: false
    }
  },
  sourceMap: true
}),

See my files above for reference.

Hope this helps someone. It solved my issue.

2reactions
curtjenkcommented, Jun 5, 2018

I’m using vue2-editor with the laravel framework. What worked for me was to revert to an older version of vue2-editor in my package.json (“vue2-editor”: “2.4.3”)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Vuejs App works in dev breaks in production -- build errors
My Vuejs app runs successfully in dev localhost but once I run the build command I get these difficult-to-debug errors.
Read more >
quill-image-resize-module-fork-for-vue2-editor - npm package
ImageResize: {} } });. Functionality is broken down into modules, which can be mixed and matched as you like. For example, the default...
Read more >
Vue.js Studies
Components are blocks of code, grouped together within a custom element. They make applications more manageable by breaking up the whole into reusable...
Read more >
vue项目中富文本编辑器踩坑之旅 - 掘金
在官网看到了这个 issues ,题目是: Production Build is breaking Vue2-editor #104 ,日期为 2018-5-18 ,还没有解决方案,只好放弃.
Read more >
A curated list of awesome things related to Vue.js
Build an e-commerce site with vue-router, vuex and vue-resource ... Deploy Vue.js — SSR(Vuetify) on Production with Pm2 and Nginx ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found