Paul
Paul

Reputation: 625

Vuejs module not found error can't resolve '@/components/ error using webpack

I cant find the answer to this other than apparently it is something to do with the webpack config, something I know nothing about.

I want to use the following way of getting to my app directory running webpack-simple template @/components/ but for me it just generates an error

module not found error can't resolve '@/components/ error

from the reading i have done there is something i need to set up in the webpack config to make this work but I cant find what it is, can anyone assist please?

At the moment im trying this in the dev server but obviously keen to make sure it will also woork in production

Ihave found this js code that I think does what I want but no idea how I would make this work with the webpack set up as never used it before

thanks

{
  "compilerOptions": {
      "baseUrl": ".",
      "paths": {
          "@/*": [
              "src/*"
          ]
      }
  }
}

Thanks

Upvotes: 8

Views: 22894

Answers (3)

Junaid Nazir
Junaid Nazir

Reputation: 383

I had the same error. @sebastian & @Mattias helped me to get the exact solution.

My configuration is

const { VueLoaderPlugin } = require("vue-loader");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  mode: "development",
  entry: "./src/main.ts",
  target: "web",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].bundle.js",
    publicPath: "/",
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".vue", ".json"],
    alias: {
      "@/": path.resolve(__dirname, "src"),
      "@/vuex": path.resolve(__dirname, "src/vuex"),
    },
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        include: /src/,
        loader: "ts-loader",
        options: {
          transpileOnly: true,
          appendTsSuffixTo: [/\.vue$/],
        },
      },
      {
        test: /\.vue$/,
        loader: "vue-loader",
        options: {
          loaders: {
            scss: "vue-style-loader!css-loader!sass-loader",
            sass: "vue-style-loader!css-loader!sass-loader?indentedSyntax",
          },
        },
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.s[ac]ss$/i,
        use: ["vue-style-loader", "css-loader", "sass-loader"],
      },
      {
        test: /\.(png|svg|jpe?g|gif)$/i,
        loader: "file-loader",
        options: {
          outputPath: "assets",
        },
      },
    ],
  },
  plugins: [
    new VueLoaderPlugin(),
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "public", "index.html"),
      filename: "index.html",
      favicon: "./public/favicon.ico",
    }),
    // make sure to include the plugin for the magic
  ],
  optimization: {
    moduleIds: "hashed",
    runtimeChunk: "single",
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
          priority: -10,
          chunks: "all",
        },
      },
    },
  },
};

Focus on this part

resolve: {
    extensions: [".ts", ".tsx", ".js", ".vue", ".json"],
    alias: {
      "@/": path.resolve(__dirname, "src"),
      "@/vuex": path.resolve(__dirname, "src/vuex"),
    },
  },

The custom defined resolve function didn't work for me but directly using the path.resolve() function helped me to avoid this error.

Upvotes: 2

Mattias
Mattias

Reputation: 725

I use this template: https://github.com/vuejs-templates/webpack.

In the already created webpack.base.conf, this is part of the exported config object (I include more than relevant to give context):

    module.exports = {
      context: path.resolve(__dirname, '../'),
      entry: {
        app: './src/main.js',
      },
      plugins: [
        // make jquery available for all modules
        new webpack.ProvidePlugin({
          $: 'jquery',
          jQuery: 'jquery',
        })
      ],
      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'),
        }
      },

This is the part that might help you:

      resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
        }
      },

Now in my imports, I just write something like

    import myModule from '@/fileInSrcFolder';

where @ is the src folder inside the root folder.

Just for completion, the config file is inside a folder in the root folder, and the resolve function looks like this:

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

Upvotes: 6

Tiến Kếu
Tiến Kếu

Reputation: 31

The only thing I do with Webpack is create an alias so that @ points to the js root directory. This removes the need for relative paths when importing files. Add the following code to webpack.mix.js.

mix.webpackConfig({    
  resolve: {      
    alias: {
 @’: __dirname + '/resources/assets/js'      
    },    
  },  
})

https://medium.com/@sadnub/vuejs-and-laravel-api-part-2-711c4986281c

Upvotes: 3

Related Questions