v0.17.0
版本发布时间: 2018-07-25 22:16:24
quasarframework/quasar-cli最新发布版本:0.17.26(2019-07-11 18:06:00)
This is a big release, introducing SSR. Enjoy!
New
SSR mode (+ optional PWA takeover)
-
quasar.conf.js new prop, specific to SSR (all sub-props are optional)
// quasar.config.js return { // ... ssr: { pwa: true/false, // should a PWA take over (default: false), or just a SPA? componentCache: {...} // lru-cache package options } }
-
Production server When you add SSR mode (
$ quasar mode -a ssr
), you will notice a new folder gets created:/src-ssr
. This folder contains your production server which you can fully customize. You can learn more about it by opening/src-ssr/index.js
file and reading the comments. -
App plugins
- Ability to tell if to get embedded only on server or only on client
// quasar.conf.js return { // ... plugins: [ 'some-plugin', { path: 'some-other', server: false } // this plugin gets embedded only on client-side { path: 'third', client: false } // this plugin gets embedded only on server-side ] }
- The default exported function now has one more property received on its Object parameter:
When you add such references (// some app plugin export default ({ app, ..., ssrContext }) => { // ssrContext has: { url, req, res } // You can add props to the ssrContext then use them in the src/index.template.html. // Example - let's say we ssrContext.someProp = 'some value', then in index template we can reference it: // {{ someProp }} }
{{ someProp }}
) into your src/index.template.html, make sure you tell Quasar it's only valid for SSR builds:<!-- index.template.html --> <% if (htmlWebpackPlugin.options.ctx.mode.ssr) { %>{{ someProp }} <% } %>
- Ability to tell if to get embedded only on server or only on client
-
extendWebpack()
&chainWebpack()
now receive one more parameter (Object), currently containing isServer or isClient boolean props:// quasar.conf.js build: { extendWebpack(cfg, { isServer, isClient }) { ... } }
This is because the
extendWebpack()
&chainWebpack()
are called twice, once for the client Webpack config and once for the server Webpack config. So by looking at the two props you can make decisions.
SSR mode (ONLY) small required changes
These changes will be required by the Quasar CLI only when you build with SSR mode. After doing these changes you'll still be able to build the other modes (SPA/PWA/Cordova/Electron) too.
src/router/index.js
You need to have a default export set to "function ({ store })" which returns a new instance of Router instead of default exporting the Router instance itself.
// OLD WAY
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
Vue.use(VueRouter)
// in the new way, we'll wrap the instantiation into:
// export default function ({ store }) --> store is optional
const Router = new VueRouter({
scrollBehavior: () => ({ y: 0 }),
routes,
// Leave these as they are and change from quasar.conf.js instead!
mode: process.env.VUE_ROUTER_MODE,
base: process.env.VUE_ROUTER_BASE,
})
// in the new way, this will be no more
export default Router
// NEW WAY
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
Vue.use(VueRouter)
// DO NOT import the store here as you will receive it as
// parameter in the default exported function:
export default function (/* { store } */) {
// IMPORTANT! Instantiate Router inside this function
const Router = new VueRouter({
scrollBehavior: () => ({ y: 0 }),
routes,
// Leave these as they are and change from quasar.conf.js instead!
mode: process.env.VUE_ROUTER_MODE,
base: process.env.VUE_ROUTER_BASE,
})
return Router
}
src/store/index.js
You need to have a default export set to "function ()" which returns a new instance of Vuex Store instead of default exporting the Store instance itself.
Some of you might need the Router instance on the Store. It is accessible through this.$router
inside your actions, mutations, etc.
// OLD WAY
import Vue from 'vue'
import Vuex from 'vuex'
import example from './module-example'
Vue.use(Vuex)
// in the new way, we'll wrap the instantiation into:
// export default function ()
const store = new Vuex.Store({
modules: {
example
}
})
// in the new way, this will be no more
export default store
// NEW WAY
import Vue from 'vue'
import Vuex from 'vuex'
import example from './module-example'
Vue.use(Vuex)
export default function () {
// IMPORTANT! Instantiate Store inside this function
const Store = new Vuex.Store({
modules: {
example
}
})
return Store
}
Also, if you want to be able to access the Router instance from vuex actions, mutations, etc, you need to make some simple changes (in all of them):
// OLD WAY:
export const someAction = (context) => { ... }
// NEW WAY:
export function someAction (context) {
// now we have access to:
this.$router
}
App Plugins
Here's a full list of the parameters for app plugins:
// ...
export default ({
app, // the Vue instantiation Object for the app
router, // the instantiated Vue Router of your app
store, // the instantiated Vuex Store (if using one)
Vue, // so you don't need to "import Vue from 'vue'"
ssrContext // the SSR context (when running server-side only)
}) => {
// ...
}
Quasar "serve" command
"$ quasar serve <...options>" creates a customizable and optimized ad-hoc static webserver that can be used for quick testing (or on production too!).
Type "$ quasar serve -h" for all the options.
# example
$ quasar serve dist/spa-mat
Tree-shaking on Quasar
This has been improved near to perfection, avoiding some webpack pitfalls. The final build of your app will include ONLY & EXACTLY what you cherry-picked from Quasar.
New quasar.conf option
- build >
showProgress
: true/false -- show/hide the compilation progress
Other new features
-
Vue component new instantiation method: preFetch() support (for all Quasar modes, not just SSR) -- works great along with the new LoadingBar Quasar plugin
// .vue component <template>...</template> <script> export default { ..., preFetch ({ store, currentRoute, previousRoute, redirect, ssrContext }) { // fetch data etc... // return a Promise // ssrContext is available only server-side // no access to "this" here as preFetch() is called before // the component gets instantiated } } </script>
However,
preFetch()
is a feature on demand, so if you want to use it, you need to enable it in quasar.conf:// quasar.conf preFetch: true
-
In app code, you can now use new booleans
process.env.SERVER
andprocess.env.CLIENT
which tell if code is run on server or on client. Useful for decision making, since for SSR apps the code must be isomorphic.
Improvements
- Updated deps: webpack 4.16.1, register-service-worker 1.4.1, css-loader v1.0.0, quasar-extras v2.0.4 (Material Icons CDN v38, Fontawesome 5.1.0, Ionicons 4.2.4)
- Extract CSS to /css instead of root #141
- Ability to specify node_module paths on quasar.conf > css (example: '~flag-icon-css/css/flag-icon.css') #136
- Improve Cordova deps install after repo clone/fork
- Quasar CSS addon functionality (injects full responsive flex CSS classes) -- more on this on the final release notes
- Follow webpack recommendations of not using filename hashes for dev build #122
- Detecting if Quasar CLI is run on a CI or minimal terminal and avoiding some pitfalls (like trying to open up a browser if quasar.conf > devServer: open is "true")
- New Webpack compile progress bar -- most important feature: takes into account parallel compilations
- Information banners on dev/build commands at startup and finish
- Enable webpack scope hoisting by default (can be disabled by quasar.conf > build > scopeHoisting: false)
- Bring back quasar.conf > vendor > add, remove arrays to configure what gets into the vendor bundle and what not.
Fixes
- Quasar commands problem on Windows Node v10.3 #130
- quasar init -v
returns error #133 - vuex store presence is not detected if not using
.js
file extension #135