admin管理员组

文章数量:1392002

I'm trying to export a Vue ponent as a package, and using vue cli to build the dist. I intend to publish it on npm, but I'm currently using a symbolic link for testing purpose. However even with a simple hello-world project I can't make a valid package.

I created a project:

vue create hello-world

Then I modified the package.json:

  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --target lib --name vue-hello-world ./src/ponents/HelloWorld.vue",
    "lint": "vue-cli-service lint"
  },
  "main": "./dist/vue-hello-worldmon.js",

Then I call

npm run build

and it piles without error.

Then I make an import in a vue ponent in another project (I used a symbolic link in node_modules):

import HelloWorld from "hello-world";

On page render I get the following error:

[Vue warn]: Failed to resolve async ponent: function MediaViewerPdf() {
  return Promise.all(/*! import() */[__webpack_require__.e(62), __webpack_require__.e(46)]).then(__webpack_require__.bind(null, /*! ./viewers/MediaViewerPdf.vue */ "./vuejs/ponents/mediaViewer/viewers/MediaViewerPdf.vue"));
}
Reason: ReferenceError: require is not defined

Any idea what's happening?

Remarks:

  • using vue inspect, I checked that in webpack config that:

target: "web"

  • I already set resolve.symlinks at false on the importing project.

EDIT: I have confirmed that it doesn't e from the symbolic link, I have exactly the same error with package directly on node_modules.

Repo with whole code:

I'm trying to export a Vue ponent as a package, and using vue cli to build the dist. I intend to publish it on npm, but I'm currently using a symbolic link for testing purpose. However even with a simple hello-world project I can't make a valid package.

I created a project:

vue create hello-world

Then I modified the package.json:

  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --target lib --name vue-hello-world ./src/ponents/HelloWorld.vue",
    "lint": "vue-cli-service lint"
  },
  "main": "./dist/vue-hello-world.mon.js",

Then I call

npm run build

and it piles without error.

Then I make an import in a vue ponent in another project (I used a symbolic link in node_modules):

import HelloWorld from "hello-world";

On page render I get the following error:

[Vue warn]: Failed to resolve async ponent: function MediaViewerPdf() {
  return Promise.all(/*! import() */[__webpack_require__.e(62), __webpack_require__.e(46)]).then(__webpack_require__.bind(null, /*! ./viewers/MediaViewerPdf.vue */ "./vuejs/ponents/mediaViewer/viewers/MediaViewerPdf.vue"));
}
Reason: ReferenceError: require is not defined

Any idea what's happening?

Remarks:

  • using vue inspect, I checked that in webpack config that:

target: "web"

  • I already set resolve.symlinks at false on the importing project.

EDIT: I have confirmed that it doesn't e from the symbolic link, I have exactly the same error with package directly on node_modules.

Repo with whole code: https://github./louis-sanna/vue-hello-world

Share Improve this question edited Jul 19, 2019 at 7:47 L. Sanna asked Jul 5, 2019 at 21:27 L. SannaL. Sanna 6,5627 gold badges35 silver badges47 bronze badges 5
  • 1 So you created this ponent and you are trying to import it into another Vue project? – user2638618 Commented Jul 6, 2019 at 5:27
  • @Josef7 Correct. – L. Sanna Commented Jul 6, 2019 at 12:56
  • Try looking at this question, it sounds like you need to add some things to the vue-hello-world package.json, import as dev dependency in the other project and possibly use npm link to link packages – user2638618 Commented Jul 6, 2019 at 15:36
  • I am currently using a symbolic link for test purpose, but I do intend to publish it on npm. – L. Sanna Commented Jul 6, 2019 at 17:01
  • So the question you linked to doesn't fit my needs. – L. Sanna Commented Jul 6, 2019 at 17:04
Add a ment  | 

3 Answers 3

Reset to default 3

So I asked the question on the vue-cli repo and I got the solution! https://github./vuejs/vue-cli/issues/4245

Turns out NODE_ENV was already set at development in my shell, so it was the mode used to make the build.

Just need to set the mode explicitly and it works:

vue-cli-service build --target lib --name vue-hello-world ./src/ponents/HelloWorld.vue --mode production

You may need to add it to vue.config.js:

config
  .mode("production")

This happens due to the fact that Vue CLI Webpack setup by default does not import monjs modules, as described in your "main" field in package.json. So the problem is with the project that attempts import, not with the project that exports the ponent.

There are two ways to attempt to solve this problem.

  1. From the importing project side

You can remedy this by installing babel plugins for the project that imports your ponents and setting babel.config.js

module.exports = {
  presets: [
    '@vue/app'
  ],
  plugins: [
    '@babel/plugin-transform-modules-monjs', // leave to import .mon.js files
    '@babel/plugin-transform-modules-umd'       // leave to import .umd.js files
  ]
}

But doing this alone will not be sufficient: you also will need to import CSS that is generated with the library by adding this in your entry file

import 'hello-world/dist/vue-hello-world.css';

Note that I have only tested this using yarn link, but I have confidence that this will work with an imported separate npm module just fine.

  1. From the library side

The intent (I suppose) of the original question - how do I bundle a library so my users don't have to do this little dance each time they want to use it?

Option 1: don't bundle it - provide .vue files and sources. Just include everything in 'src' directory of your module, write a readme with explanation and be done with it. Let the importing project figure the pilation and bundling out.

Option 2: use rollup with Vue plugin to roll ponents into bundle. There is an example on how to do that. In that example you can see that your project will be able to import .esm build https://github./vuejs/rollup-plugin-vue/tree/master/cookbook/library

Not sure how you are creating the symbolic link, but you should use npm link for that. If you are still having problems (like I did myself) I would suggest you try npm-link-better:

npm install -g npm-link-better
cd vue-hello-world
npm link
cd ../hello-world
nlc -w vue-hello-world

For building ponent libraries, I suggest you have a look at vue-cli-plugin-ponent. This plugin already sets up the vue-cli project pretty well.

本文标签: