Home > Software design >  Unable to load vue-sanitize plugin in Vue.JS application
Unable to load vue-sanitize plugin in Vue.JS application

Time:11-03

I'm new to Vue and I have a problem with one plugin. I'm trying to load vue-sanitize (here: https://www.npmjs.com/package/vue-sanitize ) but I get the following error: You may need an appropriate loader to handle this file type.

The import in main.js

import Vue from 'vue'
import VueSanitize from "vue-sanitize";

Vue.use(VueSanitize);

package.json

{
  "name": "hypermega2",
  "version": "1.0.0",
  "description": "A Vue.js project",
  "author": "",
  "private": true,
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "local": "webpack-dev-server --inline --progress --config build/webpack.local.conf.js",
    "start": "npm run dev",
    "build:dev": "node build/build-dev.js",
    "build:test": "node build/build-test.js",
    "build:prod": "node build/build-prod.js"
  },
  "dependencies": {
    "axios": "^0.19.1",
    "html-loader": "^0.5.5",
    "moment-business-days": "^1.2.0",
    "node-sass": "^4.13.0",
    "sass-loader": "^7.3.1",
    "v-calendar": "^1.0.1",
    "vee-validate": "^3.4.5",
    "vue": "^2.5.2",
    "vue-i18n": "^8.22.2",
    "vue-moment": "^4.1.0",
    "vue-mq": "^1.0.1",
    "vue-paginate": "^3.6.0",
    "vue-plain-pagination": "^0.3.0",
    "vue-quill-editor": "^3.0.6",
    "vue-router": "^3.0.1",
    "vue-sanitize": "^0.2.2",
    "vue-toast-notification": "^0.6.0",
    "vue-unique-id": "^3.2.1",
    "vuex": "^3.1.2",
    "vuex-persist": "^2.2.0"
  },
  "devDependencies": {
    "autoprefixer": "^7.1.2",
    "babel-core": "^6.22.1",
    "babel-helper-vue-jsx-merge-props": "^2.0.3",
    "babel-loader": "^7.1.1",
    "babel-plugin-external-helpers": "^6.22.0",
    "babel-plugin-syntax-jsx": "^6.18.0",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-plugin-transform-vue-jsx": "^3.5.0",
    "babel-preset-env": "^1.3.2",
    "babel-preset-stage-2": "^6.22.0",
    "chalk": "^2.0.1",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.28.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "file-loader": "^1.1.4",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "html-webpack-plugin": "^2.30.1",
    "node-notifier": "^5.1.2",
    "optimize-css-assets-webpack-plugin": "^3.2.0",
    "ora": "^1.2.0",
    "portfinder": "^1.0.13",
    "postcss-import": "^11.0.0",
    "postcss-loader": "^2.0.8",
    "postcss-url": "^7.2.1",
    "rimraf": "^2.6.0",
    "semver": "^5.3.0",
    "shelljs": "^0.7.6",
    "uglifyjs-webpack-plugin": "^1.1.1",
    "url-loader": "^0.5.8",
    "vue-loader": "^13.3.0",
    "vue-style-loader": "^3.0.1",
    "vue-template-compiler": "^2.5.2",
    "webpack": "^3.6.0",
    "webpack-bundle-analyzer": "^2.9.0",
    "webpack-dev-server": "^2.9.1",
    "webpack-merge": "^4.1.0"
  },
  "engines": {
    "node": ">= 6.0.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

webpack.base.conf.js

'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')

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

module.exports = {
  context: path.resolve(__dirname, '../'),
  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: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
      },
      {
        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]')
        }
      }
    ]
  },
  node: {
    // prevent webpack from injecting useless setImmediate polyfill because Vue
    // source contains it (although only uses it if it's native).
    setImmediate: false,
    // prevent webpack from injecting mocks to Node native modules
    // that does not make sense for the client
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty'
  }
}

webpack.build.local.conf

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

const env = require('../config/local.env')

const webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true,
      usePostCSS: true
    })
  },
  devtool: config.build.productionSourceMap ? config.build.devtool : 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: config.build.productionSourceMap,
      parallel: true
    }),
    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css'),
      // Setting the following option to `false` will not extract CSS from codesplit chunks.
      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 
      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
      allChunks: true,
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: config.build.productionSourceMap
        ? { safe: true, map: { inline: false } }
        : { 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: 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 vendor modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // enable scope hoisting
    new webpack.optimize.ModuleConcatenationPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks (module) {
        // 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',
      minChunks: Infinity
    }),
    // This instance extracts shared chunks from code splitted chunks and bundles them
    // in a separate chunk, similar to the vendor chunk
    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
    new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),

    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})

if (config.build.productionGzip) {
  const 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) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig

.babelrc

{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-vue-jsx", "transform-runtime", "external-helpers"]
}

The complete error stack :

 ERROR  Failed to compile with 5 errors                                 11:44:47

 error  in ./node_modules/sanitize-html/node_modules/postcss/lib/document.js

Module parse failed: Unexpected token (10:30)
You may need an appropriate loader to handle this file type.
|   constructor(defaults) {
|     // type needs to be passed to super, otherwise child roots won't be normalized correctly
|     super({ type: 'document', ...defaults })
|
|     if (!this.nodes) {

 @ ./node_modules/sanitize-html/node_modules/postcss/lib/postcss.js 10:15-36
 @ ./node_modules/sanitize-html/index.js
 @ ./node_modules/vue-sanitize/dist/vue-sanitize.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8120 webpack/hot/dev-server ./src/main.js

 error  in ./node_modules/sanitize-html/node_modules/postcss/lib/declaration.js

Module parse failed: Unexpected token (12:19)
You may need an appropriate loader to handle this file type.
|       typeof defaults.value !== 'string'
|     ) {
|       defaults = { ...defaults, value: String(defaults.value) }
|     }
|     super(defaults)

 @ ./node_modules/sanitize-html/node_modules/postcss/lib/postcss.js 4:18-42
 @ ./node_modules/sanitize-html/index.js
 @ ./node_modules/vue-sanitize/dist/vue-sanitize.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8120 webpack/hot/dev-server ./src/main.js

 error  in ./node_modules/sanitize-html/node_modules/postcss/lib/lazy-result.js

Module parse failed: Unexpected token (146:21)
You may need an appropriate loader to handle this file type.
|
|     this.result = new Result(processor, root, opts)
|     this.helpers = { ...postcss, result: this.result, postcss }
|     this.plugins = this.processor.plugins.map(plugin => {
|       if (typeof plugin === 'object' && plugin.prepare) {

 @ ./node_modules/sanitize-html/node_modules/postcss/lib/postcss.js 5:17-41
 @ ./node_modules/sanitize-html/index.js
 @ ./node_modules/vue-sanitize/dist/vue-sanitize.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8120 webpack/hot/dev-server ./src/main.js

 error  in ./node_modules/sanitize-html/node_modules/postcss/lib/fromJSON.js

Module parse failed: Unexpected token (14:27)
You may need an appropriate loader to handle this file type.
|   if (Array.isArray(json)) return json.map(n => fromJSON(n))
|
|   let { inputs: ownInputs, ...defaults } = json
|   if (ownInputs) {
|     inputs = []

 @ ./node_modules/sanitize-html/node_modules/postcss/lib/postcss.js 9:15-36
 @ ./node_modules/sanitize-html/index.js
 @ ./node_modules/vue-sanitize/dist/vue-sanitize.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8120 webpack/hot/dev-server ./src/main.js

 error  in ./node_modules/sanitize-html/node_modules/postcss/lib/input.js

Module parse failed: Unexpected token (234:19)
You may need an appropriate loader to handle this file type.
|     }
|     if (this.map) {
|       json.map = { ...this.map }
|       if (json.map.consumerCache) {
|         json.map.consumerCache = undefined

 @ ./node_modules/sanitize-html/node_modules/postcss/lib/postcss.js 15:12-30
 @ ./node_modules/sanitize-html/index.js
 @ ./node_modules/vue-sanitize/dist/vue-sanitize.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8120 webpack/hot/dev-server ./src/main.js

I don't know what's wrong.

Other information :

  • Node version v16.15.0

Kind regards

CodePudding user response:

Solved it :

  • Updated babel-core to v6.26.3
  • Updated babel-preset-env to v1.7.0
  • Added babel-plugin-transform-object-rest-spread to dev dependancies
  • Plugin added to .babelrc file :
{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-vue-jsx", "transform-runtime", "transform-object-rest-spread"]
}
  • Updated webpack base config:
{
    test: /\.js$/,
    loader: 'babel-loader',
    include: [
        resolve('src'), 
        resolve('test'), 
        resolve('node_modules/webpack-dev-server/client'),
        resolve('node_modules/sanitize-html/node_modules')
    ]
},

But still getting an error :

Uncaught ReferenceError: exports is not defined webpack:///node_modules/sanitize-html/node_modules/htmlparser2/lib/index.js?2133

EDIT: changed the configuration in .babelrc to

"modules": "commonjs"
  • Related