webpack-simple icon indicating copy to clipboard operation
webpack-simple copied to clipboard

Hosting from a subdirectory

Open david-saint opened this issue 6 years ago • 8 comments

I'm trying to host a vue app on a subdirectory like https://my.site/folder/ but every time it tries looking for it in https;//my.site/dist/build.js. Even when I changed the index.html to point to dist/build it finds the build file but nothing displays I'm also using vue-router I've checked online but all I keep seeing are to change config/index.js

export.module = {
...
assetsPublicPath: '/folder/'
...
}

but this is for the webpack template.

david-saint avatar Jun 13 '18 12:06 david-saint

Hi david, i solved this problem with 2 things:

first create a file vue.config.js in the project root, in same level of package.json

put this content: module.exports = { baseUrl: '/yoursubfolder/' }

then in route.js

export default new Router({ mode: "history", base: "yoursubfolder",

jcav2 avatar Sep 18 '18 21:09 jcav2

@jcav2, this worked like a charm. Thank you for posting this solution; it's saved me countless hours of fiddling and debugging.

tonmcg avatar Apr 01 '19 02:04 tonmcg

Hi david, i solved this problem with 2 things:

first create a file vue.config.js in the project root, in same level of package.json

put this content: module.exports = { baseUrl: '/yoursubfolder/' }

then in route.js

export default new Router({ mode: "history", base: "yoursubfolder",

not working on server subfolder....

simeq-manish01 avatar Apr 19 '19 06:04 simeq-manish01

Hi,

I managed to make it work but in my case I'm trying to run 2 separate Vue applications under the same host.

For example;

Root Vue app: mysite.com Second Vue app: mysite.com/secondApp

Now the issue is routing in the second Vue app. If there's a sub route in the second Vue app, accessing those routes directly resolves to the root Vue app.

For example; Access directly 'www.mysite.com/secondApp/profile' resolves to the root Vue app.

Only partial workaround I could come up with is to remove the history mode from the second vue app and then including hash in the url when directly accessing.

For example; Access directly 'www.mysite.com/secondApp/#/profile' resolves to correct Vue app.

Any idea how to achieve this when hosting from a subdirectory when running multiple Vue apps?

laygir avatar Sep 15 '19 17:09 laygir

Hi david, i solved this problem with 2 things:

first create a file vue.config.js in the project root, in same level of package.json

put this content: module.exports = { baseUrl: '/yoursubfolder/' }

then in route.js

export default new Router({ mode: "history", base: "yoursubfolder",

Instead of "baseUrl" try "publicPath"

BitaShamsafar avatar Sep 17 '19 14:09 BitaShamsafar

In this project template, what decides how to build application is webpack, and you configure it via webpack.config.js.

To change how webpack builds it for production, go to the webpack.config.js part with if (process.env.NODE_ENV === 'production') { line. Everything inside that implication (if statement) is basically "changes to the project for build process".

So, to change public path, from where everything is hosted, you will need to change publicPath value. As you see it right now in webpack.config.js, it is equal to /dist/.

If you project is served from /subdirectory, then you will have to change publicPath value to /subdirectory/dist/. To do that, simply add at within previously mentioned IF statement line like this:

module.exports.output.publicPath = '/subdirectory/dist/'

That would probably result in webpack.config.js similar to this (look for addition at the bottom of the file):

var path = require('path')
var webpack = require('webpack')

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ],
      },{{#sass}}
      {
        test: /\.scss$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader'
        ],
      },
      {
        test: /\.sass$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader?indentedSyntax'
        ],
      },
      {{/sass}}
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            {{#sass}}
            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
            // the "scss" and "sass" values for the lang attribute to the right configs here.
            // other preprocessors should work out of the box, no loader config like this necessary.
            'scss': [
              'vue-style-loader',
              'css-loader',
              'sass-loader'
            ],
            'sass': [
              'vue-style-loader',
              'css-loader',
              'sass-loader?indentedSyntax'
            ]
            {{/sass}}
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true,
    overlay: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
  module.exports.output.publicPath = '/subdirectory/dist/'
}

And another thing is with index.html. You see, the file is generated at the very beginning, when you create your project from this template. When you send it to the hosting place, you will have to change the path to dist directory too in <script src="/dist/build.js"></script>. You can change it either to relative dist/build.js (without leading slash) or absolute /subdirectory/dist/build.js - its up to you.

That would probably result in index.html similar to this (look for src attribute value change at bottom of the file):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>{{ name }}</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="dist/build.js"></script>
  </body>
</html>

Deele avatar Dec 06 '19 10:12 Deele

Hi, can the base option in the vue-router be in an array?

I-am-abdulazeez avatar Jan 16 '20 10:01 I-am-abdulazeez

Hi david, i solved this problem with 2 things: first create a file vue.config.js in the project root, in same level of package.json put this content: module.exports = { baseUrl: '/yoursubfolder/' } then in route.js export default new Router({ mode: "history", base: "yoursubfolder",

Instead of "baseUrl" try "publicPath"

Thank you, this worked for me

jhonarendra avatar Nov 28 '20 05:11 jhonarendra