Vue custom (cli ?) project generator - javascript

All my VueJS projects use at the beginning the same baseline :
Vuex
Vue Router
Immutable.js
MathJS
MomentJs
ChartJS
Plus, all my projects have quite the same "index.js" file.
Is there a way to have a command line (preferably based on Vue CLI) that can generate a project with a pre-coded "index.js" file and a package.json with those above dependencies ?

It sounds like you are wanting to use the Vue CLI to create a project. However, you additionally want some default npm packages to be installed and imported into your index.js file.
Answer: no. this functionality does not exist (currently)
Some Suggestions:
Open a feature request here. If you did do a feature request, you should descibe it in a more general way. For example 'allow the ability to specify npm packages on project creation' opposed to specifically installing ChartJS, Moment and the other ones. That's too specific, that will get shot down and closed in a heart beat.
Create a repo with the project structure and packages you want and always start from that repo (opposed to using vue cli)
Write your own custom node cli to interface with vue cli that handels your extra steps for you. You could easily write a node (console program) that executes the steps you want. Basically, create the vue project, npm install what you need, generate an index.js with your package imports.
I think the easiest route is to just create an empty vue project how you want it. Save that repo as 'vue-boilerplate' or something and just always start off with that empty project opposed to doing vue create every time.
In my personal opinion, I think going through all this to npm install 3 packages and add the imports to a js file isn't entirely worth it unless you find yourself creating a massive amount of projects that will all require the exact same setup.
Angular has a similar idea called schematics but I do not see an equivilant within Vue as of yet.

Related

Other way to share react ts components between projects

I have been looking for a way to mostly share some code between projects specifically for SPFX and fluent ui. We found 3 main ways to do that.
1.
Creating a component library is the way that seemed least complicated cause it uses the same infrastructure and do all building without the need to configure it.
But this adds some issues, we need to built and manually link the solution locally to make it work, this will also work if we put in a repo. so this is mitigated.
The second is that implicitly this will also require the fluent ui and react. Plus having to place it inside a SPFX component library project.
2.
I saw some promise using paths in ts and this works fine while using the ts compiler. It will go to the folder that your proj is referring and build it at calling time. which is great. But it did not work in SPFX.
3.
Another way was to have a post install to sync the folders which seems easy enough but I wonder how practical this is plus how people are doing it, if they are, how.
All I wanted to figure out now is a way to take my component code and share as if they were in a folder of my src or a simple extension of the code. No need to have extra dependencies or build steps, just the code that can be used as a ts/tsx file. ex:
shared lib:
//assuming I have react and fluentui already installed for the project.
import button from 'fluentui';
export const fancyCustomButtom = (props) => {
return (<Button text="Standard" />);
};
src project folder:
import {fancyCustomButtom} from 'shared-lib'
It is fine if it needs to build the files before we can use it but can we do it at build time or when the package is installed? also wouldn't it increase my bundle size by making both module dependent on things already available (react, fluentui)?
Given the way Microsoft have architected the loading of bundles in SharePoint and Teams - I believe an SPFX component library is the best way to share code between different solutions, particularly if you are looking to minimise bundle size...
Imagine you have a library for something re-usable: a form, a set of standard branded components - something of that nature. You could put your shared code in repos and add references to it - either by publishing your own repo publicly or using the npm install git+https://yourUrl syntax; but what effectively happens there is that your code is pulled down in to node_modules for each project, and any referenced module code is included in your bundles. If you have two, three, four or more webparts on the same page - using those same libraries, you're multiplying how many times that code is included on the page.
If you follow Microsoft's guide on setting up a component library project however, your npm link commands allow your types to be recognised in consuming projects without needing to actually include the bundled distribution code. You can deploy your library code once to the App Catalog, and if it's referenced in other solutions -- it's loaded on pages as needed: once.
I have found the development experience to be quite flaky at times, but it does work. When I run gulp clean on my library code, or come back to it after some time, I sometimes find that I need to run npm link and npm link my-project-name again as per the instructions in the above tutorial. Whenever you run gulp build on your library, you should also rebuild the project that consumes the library, either by using gulp build / bundle or by saving a file (if you're running gulp serve). This process works well for developing, and once it comes time to deploy, all you need to do is add a named reference to your library inside package.json and then deploy both .sppkg files to your App Catalog.
In terms of your last question re: bundle size - react is not actually included in the dependencies for an SPFX library project, but you will find it's available to use. When you build your library, if you take a look in the generated javascript in your dist folder, you will see it's listed as one of the dependencies for the webpacked content along with react-dom and ControlStrings. It's on line 1.
office-ui-fabric-react is included as a devDependency thanks to the #microsoft/sp-webpart-workbench package that gets scaffolded with all SPFX projects - and if you check your library's dist javascript, you will see that included components are being webpacked and included in your bundle. I'm not entirely sure if when you pull this code in to your consuming project, whether webpack then tree-shakes to de-duplicate and ensures only necessary code is included: I don't know. Someone else may be able to illuminate us there or provide a more accurate explanation of what's going on... I will update this response if anyone comments to let me know.
And finally, this is more of a personal way of working, but it may be worth consideration:
When developing a library, I sometimes reference it in other projects via a local npm install ../filepath command. This ensures that when I install the library as described, the consuming project installs any necessary dependencies. I'm able to tweak both projects if I need o. When it comes time to deploy, I commit my changes to both projects, deploy my library code to the App Catalog, and then npm uninstall the library from the consuming project and add a reference as described in the above tutorial. When I deploy projects that use my library, they just work.
I recently developed a library that uses pnpjs, in particular the #pnp/sp library that is used to talk to SharePoint. If you look at the Getting Started guide for that library, they expect you to pass a reference to your Application Customizer or Web Part context during setup, or explicitly set things up using a base URL and so forth - and of course, a library doesn't really have a page context of any sort - the whole point of this code is that it's reusable. So that poses a challenge. My solution was to do the setup in the consuming web part(s) and ensure that they pass a reference to the sp object (which is of type SPRest) to any code or components that exist in my library. My library has peerDependencies on those pnp libraries so that the code isn't duplicated in consuming projects. Sometimes you have to think about what your library needs to include in its bundle and what you expect consuming solutions to already have, and maybe find ways to ensure things aren't included that aren't needed.
For example, in the scenario you talk about, you may want to ensure fluentui or office-ui-fabric-react are only devDependencies or peerDependencies for your library. As long as your library and the project(s) consuming your library both use the right version(s) you shouldn't have any trouble, and you can document any pre-requisites with your library documentation. You can check which versions of these libraries are installed per the SPFX version you are currently using ie. SPFX v1.11 or v1.12 etc. Just run npm ls <packagename> to get a breakdown, or check your package.json file.

The global CKEDITOR_VERSION constant has already been set on vue

I am creating Vue spa and integrating CKEditor here using this package I tried to do just like the tutorial by adding this to my app.js
import Vue from 'vue'
import ClassicEditor from '#ckeditor/ckeditor5-build-classic'
import documentEditor from '#ckeditor/ckeditor5-build-decoupled-document'
import VueCkeditor from 'vue-ckeditor5'
const options = {
editors: {
classic: ClassicEditor,
document: documentEditor
},
name: 'ckeditor'
}
Vue.use(VueCkeditor.plugin, options);
and to make it work I doing NPM install to those 2 editors (ClassicEditor and documentEditor)
npm install --save #ckeditor/ckeditor5-build-decoupled-document
and since I also need CKEditor but with much more simpler or to being said without image upload features then I for the ckeditor5 build classic and remove those plugin from there and then NPM build and then I am doing this on my Vue spa
npm install --save #ckeditor/ckeditor5-build-classic
after that, I open #ckeditor folder on node_modules and find the ckeditor5-build-classic folder and replace build folder with my custom version of CKEditor build classic
but then I get this error
ckeditor-version-collision: The global CKEDITOR_VERSION constant has already been set.
even though the editor still working, but I don't like the idea my console showing error
This problem is precisely described in docs, you can't run two editors from different builds on the same page (or mixing builds and source code).
tl;dr; The easiest way to enable running two different editors on the same site is to create a custom build that will export these two builds. This is described in the above docs.
The behavior has changed ~3 months ago and the error has been added to such situation to prevent bugs and big size of the bundle. Therefore the author of the https://github.com/igorxut/vue-ckeditor5 can just update the readme to follow the latest version's API.
I recommend to create "super build".
For example you can clone repository of classic build and change 3 files.
Check my gits.
I updated example1 for using this build.

Publish Aurelia component on NPM?

We have built a small-ish application using Aurelia, and would like to be able to integrate the app into a larger codebase. For example, it may be desirable to publish the Aurelia app on NPM, so other projects could integrate our code.
How can we build/publish the Aurelia app, so that it can be instantiated in a larger JavaScript application?
Typically, you wouldn't publish an entire Aurelia application to NPM, rather you would push plugins to NPM.
The simplest way to learn how to do this is to follow the example of the various Aurelia repos. We build the code in to multiple formats, but the most important are AMD and CommonJS (which is more important for your company is dependent on what tooling your company is using). Once you've built the code, the next step is to make sure your package.json file is set up correctly. It's best to copy the example of what we're doing in our own repos.
I would start by looking at either the dialog plugin or the templating-resources plugin. Both of these show good examples of how to publish your Aurelia plugin to NPM, whether it is a public or private npm feed.
https://github.com/aurelia/dialog/blob/master/package.json
https://github.com/aurelia/templating-resources/blob/master/package.json
Both of these plugins are set up to support Webpack, JSPM/SystemJS, and the Aurelia CLI out of the box.
I totally agree with #Ashley in not publishing larger applications to the global NPM registry. The big advantage of it is the simplicity of all that small packages which can be used to build large applications.
If you feel you got some reusable code, put in an own package and publish it.
Anyway, to give you an answer which does not require you to publish your complete app: you can include a complete repository (which is probobly what you are lookig for) in a different application via NPM.
npm install git://github.com/somegit/hubrepo.git
Or directly via the package.json:
"dependencies": {
"private-repo": "git+ssh://git#github.com:somegit/hubrepo.git#v1.0.0",
}
You can also do something similiar e.g. using JSPM. This would be simply:
jspm install your-app=github:OrgOrUser/your-app#your-branch
If you are facing long relative paths in your imports now, depending on your tooling, you may be interested in something like e.g. Resolving require paths with webpack which shows how to alias relative paths.
Sources/Links:
How to install a private NPM module without my own registry?
npm install private github repositories by dependency in package.json

NPM: should I use one of my dependencies' dependencies, or should I explicitly install it into the project at the root level?

TL;DR Summary
(I'm using Lodash as an example here, but it could be any other package)
In addition to using Lodash for its own purposes, my application also needs to import JavaScript from an NPM package that I created. The JavaScript in this package relies on Lodash as well. It's possible that each codebase may have installed a different version of Lodash. If JavaScript in my application and JavaScript in the installed package both import the same Lodash functions, then I want to avoid having to bundle two different versions of the same function. I understand that NPM is able to resolve the dependencies and that nothing will break, but the size of my application's JavaScript bundle will continue to grow as each codebase uses functions from different versions of the same libraries. It sounds like the only way to keep the versions in sync is to continuously monitor them and upgrade manually when appropriate, or to use the version provided by the installed package directly, without ever installing it into my application's own package.json. Is doing the latter a bad idea and is there no better way?
Original Question
At my company, we've created a Git repository that houses most of our UI component code. This repository also contains a static site generator, which transforms our UI component code into a "living style guide" website. The purpose of this website is to document and showcase our UI components on the web (similar to how PatternLab works).
We also distribute this code via NPM, so that it can be shared across multiple projects. Each project installs the NPM module as a dependency, then imports the SASS and JavaScript files contained within. The JavaScript has been written in ES6 and has not been bundled or transpiled. We've intentionally chosen not to distribute browser-ready code. Instead, each project is responsible for compiling its own SASS and bundling/transpiling its own JavaScript.
Most of our UI component JavaScript is simple and does not depend on any third-party libraries, so it's easy to import into our projects. However, some of our newer, more complex components rely on NPM packages such as Lodash, which presents a problem.
Obviously, we need to install Lodash in order for the static site generator to showcase our Lodash-reliant components inside of a web browser. Similarly, projects that consume the NPM package will also need to install Lodash, in order to create instances of these same components. This forces us to install Lodash twice: once in the UI component project, then again in the project that consumes the NPM package. This is problematic because the two projects could potentially install different versions of Lodash, which could lead to compatibility issues and/or increase the size of our JavaScript bundle.
One solution that I've discovered is to include Lodash under dependencies instead of devDependencies, in the UI component project. This way, when external projects install the UI component NPM module, Lodash will be installed along with it. This gives the project "free" access to Lodash without needing to explicitly install it itself. This is possible because NPM installs packages in a single, flat directory hierarchy, so it doesn't seem to matter if your project installs a package directly or if one of its dependencies exposes it as a dependency in it's own package.json. This eliminates version conflicts, since you don't have to install the package twice.
My question is, does this violate NPM best practices or is this how NPM is intended to work? After reading the NPM documentation and Googling for answers, it doesn't seem like this should be a problem. However, if what I'm suggesting is a bad idea, how else can I accomplish what I'm trying to do?
Here's a quick visual aid:
main.js
node_modules/
lodash/
foo/
bar.js
node_modules/
lodash/
main.js imports and uses Lodash. It also imports foo/bar.js, which uses Lodash too, but a potentially different version. Both files are ES6. main.js gets bundled and transpiled before being sent to the browser.
if is something you are directly using you should specify it in your package.json. it will be installed anyways but this way it will ensure that if your dependency removes that package as a dependency your project won't break

Meteor 0.9 Local Package Location

I noticed that somehow there is no packages folder in my newly created Meteor 0.9 project. This means that it must be using package from the ~/.meteor things. However, I cannot work like this as I am hopping between machines all day and I would like the package to stay locally; like in the project folder itself.
In the previous Meteor 0.8.3 project, I manually created packages folder in the project and when I add package it went inside there (for example i can find collectionFs inside package/ in the project directory).
I want it to be like this. How can I do this safely?
You can still drop packages into the top-level "packages" directory inside your project and then run meteor add like usual. These packages are just treated as app-specific packages. Here are the docs about using packages. The relevant bit is quoted here:
In addition to the packages in the official Meteor release being used by your app, meteor list and meteor add also search the packages directory at the top of your app.
I think the idea was to delineate the stand-alone application code from 3rd party libraries. As a package author, this means there are less forks of my library with subtle changes floating around on Atmosphere. It also makes your apps a bit less prone to bugs (given the packages are stable), and encourages better package maintenance.
If you want to use local packages though, here is a good walk-through.
For NPM packages, also check out meteorhacks:npm | github
For the collectionFS, you have to use meteor 0.6 version.
You have to add new release file of meteor 0.6 version.
https://github.com/CollectionFS/Meteor-cfs-example-filemanager

Categories

Resources