1

After implementing lazy loading in my routes like this:

component: () => import('./pages/home/index/index.vue')

locally it kinda works (loses fonts on certain routes).

When code is deployed by CI/CD environment, any route that is setup with lazy loading is not loaded in browser , with this console error:

Uncaught SyntaxError: Unexpected token <

After inspecting the problem, it points to <head> tags, and inside I have this:

<link href=/dist/static/css/app.4d19fef0c231f16b8783490b2895fe94.css rel=stylesheet><link href=/dist/static/css/app.1fa1a352ec9d24165aab94b33bba4db2.css rel=stylesheet>

which are split css files in final bundle.

So that tells me I haven't configured something nicely in webpack config perhaps ?

Help with this is appreciated.

webpack config is standard vue-cli config (this is prod config):

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 env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  // The following line must be used for production because of the 
  // folder structure we have in the packaged app.  
  //context: __dirname + "/../../app",

  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 webpack.optimize.UglifyJsPlugin({
     // Eliminate comments
        comments: false,

    // Compression specific options
       compress: {
         // remove warnings
            warnings: false,

         // Drop console statements
            drop_console: 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(),
    // 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'
    }),
    // 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

build prod settings:

 build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../index.html'),
//    index: path.resolve(__dirname, '../dist/index.html'),
    assetsRoot: path.resolve(__dirname, '../dist'),
//    assetsSubDirectory: '/static',
    assetsSubDirectory: 'static',
//    assetsPublicPath: '/app/dist/',
   assetsPublicPath: '/',
    // assetsPublicPath: '/dist/',
    fontPath: '/static',
    productionSourceMap: true,
    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  },
4
  • If you believe it's a problem with the webpack config, showing the webpack config would be helpful Commented Feb 22, 2018 at 13:38
  • added webpack.config.prod Commented Feb 22, 2018 at 14:15
  • Are you using a Vue Router for this? Commented Feb 22, 2018 at 14:31
  • yes, I do @RuChernChong Commented Feb 22, 2018 at 14:41

2 Answers 2

1

Since you have mentioned that you are using Vue Router for your app.

Add base: '/sub-directory/ into your Router code.

For example:

export default new Router({
  base: '/foo-bar/',
  routes
})

Also remember to set your public assets path in your webpack configuration file to have the /sub-directory/

Sign up to request clarification or add additional context in comments.

11 Comments

right now I don't have base flag explicitly set in my router config, but I do have public assets path set to '/dist'. Should I just add the same to base router config ?
Yes, you should.
I added '/dist' to router config , it's the same thing. However when I inspect network folder structure I see something like this: dist/static/js for js bundle and diststatic/js for chunks, perhaps that is the problem ? Perhaps I need to add '/dist/' ? Also I don't see why locally this works, just does not work when deployed ?
with that fix, it actually works, but I guess I will just put both router base path and assets public path to '/' , since I don't need dist sub-route.
Thanks for your help @RuChernChong
|
0

In the end I fixed problem with modifying assetsPublicPath: '/dist', to assetsPublicPath: '/dist/',.

Main problem was that my tree structure should have been dist/static/... and it was diststatic/... for chunk files

Hopefully this will help someone.

1 Comment

Where is assetsPublicPath in which file it lies?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.