Git Product home page Git Product logo

vbuild's Introduction

preview

Badges

NPM version NPM downloads Build Status donate twitter

tl;dr

vbuild whatever.js --dev
# it just works

Develop Vue apps with no build configuration until you need.

Install

It works with both Yarn(>=0.17) and npm(>=3):

yarn global add vbuild
# You can also install it locally
# yarn add vbuild --dev

How to use

The simple way (using create-vue-app)
yarn global add create-vue-app
create-vue-app my-app
# or `cva my-app`

Then follow the instructions in terminal.

Or manually, populate an entry file, let's say index.js:

import Vue from 'vue'

new Vue({
  el: '#app',
  render: h => <h1>Hello World!</h1>
})

Run app in dev mode:

vbuild index.js --dev

So far we get:

  • Automatic transpilation and bundling (with webpack and babel/postcss)
  • Hot code reloading
  • Static file in ./static/ will be copied to ./dist/

To see how simple it is, check out our official website which is built with vbuild itself.

Build app in production mode (default mode):

vbuild index.js

⬆ back to top

Config file

All CLI options and advanced options can be set here:

module.exports = (options, req) => ({
  port: 5000
  // Other options
})

// Note that you can directly export an object too:
// module.exports = {port: 5000}

By default it will load vbuild.config.js if it exists. To change the path, you can add --config [path] in CLI arguments.

You can also use .vbuildrc or set vbuild property in package.json when you only need JSON for configurations. See cosmiconfig for all the supported config files.

⬆ back to top

Shorthand

To set different config for different mode, you may use options.dev like:

module.exports = options => ({
  webpack(cfg) {
    if (options.dev) {}
    else {}
    return cfg
  }
})

To simplify this, we provide a shorthand to do this:

module.exports = {
  production: {}, // used in `!options.dev`
  development: {} // used in `options.dev`
}

The production or development config will be assigned into base config using lodash.merge.

⬆ back to top

Arguments

options

CLI options.

⬆ back to top

req

The require function but context directory is the path to node_modules/vbuild/lib, which means you can use it to load vbuild's dependencies, like webpack.

⬆ back to top

Babel

JS files and script tags in single-file components are transpiled by Babel. We only use one preset by default: babel-preset-vue-app.

vbuild will use .babelrc if it exists, you can also set babelrc option in config file to disable config file, check out full reference for babel option.

⬆ back to top

Transpile modules

By default babel will only transpile files outside node_modules folder into ES5, but you may use some npm packages that are written in ES2015, then you can tell babel to transpile them as well:

module.exports = {
  transpileModules: ['element-ready']
}

⬆ back to top

PostCSS

Standalone .css files and style tags in single-file components are transpiled by PostCSS, the only plugin we use by default is autoprefixer, and you can use autoprefixer option in config file to adjust it, here's the config with default value:

module.exports = {
  autoprefixer: {
    browsers: ['ie > 8', 'last 4 versions']
  }
}

You can use PostCSS config file like postcss.config.js or whatever postcss-load-config supports. postcss option is also available in config file.

Note that we only add autoprefixer when you use an Array or Object as postcss option.

Custom CSS preprocessors

Supported preprocessors: sass scss stylus less, the workflow of CSS is custom css preprocessor -> postcss-loader -> css-loader.

To use a custom CSS preprocessor, you can directly install relevant loader and dependency. For example, to use scss:

yarn add node-sass sass-loader --dev

CSS modules

To use CSS modules in single-file component, you can set module attribute in <style></style> tag.

To use CSS modules in standalone css files, you can set cssModules to true in config file.

⬆ back to top

Webpack entry

Type: string Array Object

You can set webpack entry from CLI option or entry property in config file. If it's an array or string, we add it into webpackConfig.entry.client entry, otherwise it will totally override webpackConfig.entry

⬆ back to top

Hot reloading

By default we add HMR client to client entry, you can change it by:

module.exports = {
  hmrEntry: ['other-name']
}

⬆ back to top

Code splitting

We enabled code splitting for vendor code and app code by default in production mode, you can set vendor option to false to disable it. And by default all required modules in node_modules will be split.

⬆ back to top

Webpack

Mutate webpack config as you wish:

module.exports = options => ({
  webpack(webpackConfig) {
    if (options.dev) {
      // Apply some changes to webpackConfig
    }
    return webpackConfig
  }
})

The value of webpack could also be a plain object, this way it will be merged into default webpack config using webpack-merge.

⬆ back to top

Custom HTML output

Type: Object Array boolean

html-webpack-plugin options, use this option to customize generated index.html, default value:

module.exports = {
  html: {
    // `pkg` indicates the data in `package.json`
    title: pkg.title || pkg.productionName || pkg.name,
    description: pkg.description,
    template: // defaults to $cwd/index.html if it exists, otherwise use built-in template
  }
}

Check out the built-in template file we use. To disable generating html file, you can set html to false.

The options for html-webpack-plugin are available in template file as htmlWebpackPlugin.options and you can use htmlWebpackPlugin.options.pkg to access the data of package.json.

⬆ back to top

Custom output filename

Set custom filename for js css static files:

module.exports = {
  filename: {
    js: 'index.js',
    css: 'style.css',
    static: 'static/[name].[ext]'  
  }
}

⬆ back to top

Clean dist files

The files inside dist folder will be removed before you run vbuild in production mode, because in most cases the output filename will contain [hash], we need to remove old files to keep the directory clean.

However in some cases you don't need this, then you can disable it by:

module.exports = {
  cleanDist: false
}

⬆ back to top

Extracting CSS

The extract option is true by default in production mode, however you can also set it manually to overrde:

module.exports = {
  // always disable extracting css
  extract: false
}

⬆ back to top

Copy static files

By default, all files inside ./static folder will be copied to dist folder, you can set it to false to disable this.

If your want it to copy other folders, use an array instead:

module.exports = {
  // copy ./public to ./dist/public
  copy: [{from: './public', to: './public'}]
}

See more options about this at copy-webpack-plugin.

⬆ back to top

Define constants at compile time

define is a short-hand to add webpack's DefinePlugin for settings global constants which can be configured at compile time.

module.exports = options => ({
  define: {
    __DEV__: JSON.stringify(options.dev)
  }
})

Then use it in your app code:

if (__DEV__) {
  // perform something only in development mode a.k.a `--dev`
}

The default constants we add is process.env.NODE_ENV. The variables you defined here are only available in app code.

⬆ back to top

Load env variables

Your project can consume variables declared in your environment as if they were declared locally in your JS files. By default you will have NODE_ENV defined.

There're three way to define env variables:

  • CLI options --env.VARIABLE_NAME xxx
  • env option in config file
  • .env file via dotenv

You can use them in index.html and app code:

# .env file
VUE_APP_DESCRIPTION=my awesome project

In template html file which uses lodash.template syntax, you can write:

<meta name="description" content="<%= htmlWebpackPlugin.options.env.VUE_APP_DESCRIPTION %>" />

In app code you access it by:

const key = process.env.VUE_APP_KEY

To totally disable loading env variables, you can set env to false.

⬆ back to top

Proxy API request

To tell the development server to serve any /api/* request to your API server in development, use the proxy options:

module.exports = {
  proxy: 'http://localhost:8080/api'
}

This way, when you fetch /api/todos in your Vue app, the development server will proxy your request to http://localhost:8080/api/todos.

We use http-proxy-middleware under the hood, so the proxy option can also be an object:

module.exports = {
  proxy: {
    '/api/foo': 'http://localhost:8080/api',
    '/api/fake-data': {
      target: 'http://jsonplaceholder.typicode.com',
      changeOrigin: true,
      pathRewrite: {
        '^/api/fake-data': ''
      }
    }
  }
}

Keep in mind that proxy only has effect in development.

⬆ back to top

Dev server

port

Type: number
Default: 4000

Port of dev server.

host

Type: string
Default: localhost

Host of dev server.

⬆ back to top

Custom server logic

Perform some custom logic to development server:

module.exports = {
  setup(app) {
    app.get('/api', (req, res) => {
      res.end('This is the API')
    })
  }
}

⬆ back to top

Custom build process

Insead of letting vbuild run webpack as the build process, you can perform a custom one by using run function in config file:

// For example, run tests with Karma
const Server = require('karma').Server

module.exports = {
  run(webpackConfig) {
    const server = new Server({
      webpack: webpackConfig,
      // ...Other karma options
    })
    server.start()
  }
}

⬆ back to top

JavaScript API

You can use vbuild as a Node.js module:

const vbuild = require('vbuild')

const config = require('./vbuild.config')
const result = vbuild(config)
//=> res:
{
  webpackConfig, // final webpack config
  options, // final options (merged config with default values)
  compiler, // webpack compiler instance
  watcher, // in watch mode, webpack watcher
  server, // in dev mode, an instance of `http.Server` without calling `.listen`
  devMiddleware // in dev mode, the webpack-dev-middleware instance
}

// get webpack config and merged options only
const result = vbuild.getConfig(config)
//=> res:
{
  webpackConfig,
  options
}

// error catch
function handleError(err) {
  if (err.name === 'AppError') {
    // error occurs in starting the compilation
  } else {
    // other unknown error
  }
}

try {
  vbuild(config)
} catch (err) {
  handleError(err)
}

⬆ back to top

Recipes

⬆ back to top

Limitations

Feel free to request new features.

FAQ

Is it like Next.js or Nuxt.js?

Yes and no, yes is because they all simplified the process of building a complete web app, while vbuild is more focusing on building single-page app without the server-side, at least it is for now.

Is it like vue-cli?

No, vue-cli is just a boilerplate generator while vbuild is a Webpack wrapper which reduces boilerplate code for you.

You may notice that there's a vue build command lying in vue-cli, that's actually quite similar to vbuild, but providing less features and vbuild goes far beyond that.

Is there a `--watch` mode?

Sure, you can combine the --watch mode with default mode and --dev mode, when it's combined with --dev mode, it will remove the hot-reloading support.

What are the differences between `--watch` `--dev` and production mode?

The default mode is production mode, i.e. without --dev.

--dev mode uses hot reloading by default, when your file does not support hot reloading it fallbacks to live reloading.

--watch can be used with/without -dev flag:

  • with --dev: no dev server, no hot reloading, since you may not need to open browser at all. It only rebuilt when file changes, all other features in dev are the same.
  • without --dev: like production mode but it rebuilt due to file changes.
What is this inspired by?

Despiting that vbuild predates Next.js create-react-app nwb vue-cli, we're heavily inspired by these projects.

⬆ back to top

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D

Author

vbuild © EGOIST, Released under the MIT License.
Authored and maintained by egoist with help from contributors (list).

egoistian.com · GitHub @egoist · Twitter @rem_rin_rin

vbuild's People

Contributors

egoist avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.