先建立一个空目录,在该目录打开命令行,执行 npm init
命令建立一个项目(没法执行 npm 命令?须要先安装 Node),这个过程会提示输入一些内容,随意输入就行,完成后会自动生成一个 package.json 文件,里面包含刚才输入的内容javascript
建立一个 index.html 页面,因为使用的是 Vue 开发单页应用,因此一般一个 html 文件就够了,内容也很简单,就一个 div#appcss
projecthtml
project-name + |- index.html |- package.json
index.htmlvue
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>这是标题</title> </head> <body> <div id="app"></div> </body> </html>
projectjava
project-name |- index.html + |- index.js |- package.json + |- webpack.config.js
建立一个 index.js 做为项目的主入口,建立一个 webpack.config.js 文件做为 Webpack 的配置文件,内容以下node
webpack.config.jswebpack
'use strict' const path = require('path') module.exports = { mode: 'development', entry: './index.js', output: { filename: 'index.js', path: path.resolve(__dirname, 'dist') } }
执行 npm install --save-dev webpack-cli
安装 Webpackios
在 package.json 文件对应的 scripts
处写入命令git
package.jsones6
{ "scripts": { + "build": "webpack" } }
执行 npm run build
便可完成打包,打包成功后的文件放在 dist 目录里面(这是由配置文件自定义的),目前打包出来的只有一个 index.js 文件
使用 webpack-dev-server 来启动本地服务,方便开发以及本地调试
执行 npm install --save-dev webpack webpack-dev-server
在 package.json 文件对应的 scripts
处写入命令
package.json
{ "scripts": { + "dev": "webpack-dev-server", "build": "webpack" } }
执行 npm run dev
便可启动本地服务,访问 localhost:8080 便可,8080 是默认的端口号,修改端口号配置以下
webpack.config.js
module.exports = { // ... devServer: { compress: true, port: 8080 } }
使用 html-webpack-plugin 来生成 HTML 文件
执行 npm install --save-dev html-webpack-plugin
在 webpack.config.js 配置文件中添加
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { // ... plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: './index.html' }) ] }
执行 npm install --save-dev vue-loader vue-template-compiler
执行 npm install --save vue vue-router
在 webpack.config.js 中配置 vue-loader 用于引入 .vue 类型文件
webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { // ... module: { rules: [ { test: /\.vue$/, use: [ { loader: 'vue-loader' } ] } ] }, plugins: [ new VueLoaderPlugin() ] }
新建一个 app.vue 文件做为路由组件的容器
project
project-name + |- app.vue |- index.html |- index.js |- package.json |- webpack.config.js
app.vue
<template> <router-view></router-view> </template> <script> export default {} </script>
index.js
import Vue from 'vue' import VueRouter from 'vue-router' import appView from 'app.vue' Vue.use(VueRouter) const router = new VueRouter({ routes: [ { path: '/', component: require('./index.vue').default } ] }) new Vue({ el: '#app', router, render(h) { return h(appView) } })
新建一个 index.vue 文件做为首页
project
project-name |- app.vue |- index.html |- index.js |- package.json + |- index.vue |- webpack.config.js
index.vue
<template> <div> <h1>这是首页</h1> </div> </template> <script> export default {} </script>
添加一个 about.vue 文件做为关于页
project
project-name + |- about.vue |- app.vue |- index.html |- index.js |- package.json |- index.vue |- webpack.config.js
about.vue
<template> <div> <h1>这是关于页</h1> </div> </template> <script> export default {} </script>
配置关于页的路由
index.js
// ... const router = new VueRouter({ routes: [ { path: '/', component: require('./index.vue').default }, { path: '/about', component: require('./about.vue').default }, ] })
访问 http://localhost:8080/#/about 便可显示关于页
随着页面的增长,vue 文件将会愈来愈多,放在项目根目录下面并不科学,在当前目录建立一个 src 目录用来放置开发源文件
在 src 目录中建立一个 pages 目录用来放置 vue 页面文件,将 app.vue、index.vue、about.vue 文件移入 pages 目录中,同时修改对应的引用路径
project
project-name - |- about.vue - |- app.vue |- index.html |- index.js |- package.json - |- index.vue |- webpack.config.js + |- /src + |- /pages + |- about.vue + |- app.vue + |- index.vue
index.js
// ... import appView from './src/pages/app.vue' const router = new VueRouter({ routes: [ { path: '/', component: require('./src/pages/index.vue').default }, { path: '/about', component: require('./src/pages/about.vue').default }, ] })
像 ./src/pages/index.vue
这种长路径写起比较麻烦,在 webpack.config.js 中配置一个 alias 参数
webpack.config.js
module.exports = { // ... resolve: { alias: { '@': path.join(__dirname, 'src') } } }
上面的页面路径能够再次改写
index.js
// ... import appView from '@/pages/app.vue' const router = new VueRouter({ routes: [ { path: '/', component: require('@/pages/index.vue').default }, { path: '/about', component: require('@/pages/about.vue').default }, ] })
同时,将路由配置单独提取出来,新建一个 routes.js 文件放在 src/js 目录中(js 目录须要新建)
project
project-name |- index.html |- index.js |- package.json |- webpack.config.js |- /src + |- /js + |- routes.js |- /pages |- about.vue |- app.vue |- index.vue
routes.js
module.exports = [ { path: '/', component: require('@/pages/index.vue').default }, { path: '/about', component: require('@/pages/about.vue').default }, ]
index.js
// ... import routes from '@/js/routes' const router = new VueRouter({ routes })
因为前面的代码使用了 ES2015 的语法,为了使项目兼容更多浏览器,须要用 Babel 对代码进行转换
执行 npm install --save-dev @babel/core @babel/preset-env babel-loader
webpack.config.js
module.exports = { // ... module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: [ { loader: 'babel-loader' } ] } ] } }
建立一个 .babelrc 文件(不知道怎么建立?能够直接从该项目中复制)
project
project-name + |- .babelrc |- index.html |- index.js |- package.json |- webpack.config.js ...
.babelrc
{ "presets": ["@babel/preset-env"] }
项目中确定会用到 CSS,首先新建一个 style.css 样式文件,项目中的样式就能够写在这里面
project
project-name |- .babelrc |- index.html |- index.js |- package.json + |- style.css |- webpack.config.js ...
而后安装 Normalize.css 用于使各类浏览器呈现一致的效果,这只是一种样式初始化方案,是可选的,另外也能够选择 Bootstrap 或者 Bulma 等包含更多样式的样式库来做为开发的基础
执行 npm install --save normalize.css
直接在 index.js 里面引用
index.js
import 'normalize.css' import './style.css' // ...
因为这里直接在 js 文件中引用了 css 文件,因此须要 css-loader 来处理
执行 npm install --save-dev css-loader style-loader
webpack.config.js
module.exports = { module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' } ] } ] } }
另外也能够在 vue 文件里面写 CSS
index.vue
<template> <div> <h1>这是首页</h1> </div> </template> <script> export default {} </script> <style> h1 { text-align: center; } </style>
两种写样式的方式能够根据具体需求选择使用
上面引入 css 的方式最终打包以后 CSS 代码都在 js 里面,为了网站的性能须要将 CSS 单独提取出来,使用 mini-css-extract-plugin 插件来提取 CSS
执行 npm install --save-dev mini-css-extract-plugin
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = { // ... module: { rules: [ { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader // 代替 style-loader }, { loader: 'css-loader' } ] } ] }, plugins: [ new MiniCssExtractPlugin({ filename: `[name].css` }) ] }
项目中若是有用到图片须要 file-loader 来处理
执行 npm install --save-dev file-loader
webpack.config.js
module.exports = { // ... module: { rules: [ { test: /\.(png|jpe?g|gif)$/i, loader: 'file-loader' } ] } }
准备一张图片 logo.gif 放在 src/images 目录中(images 目录须要新建,这张图片是用来测试的)
project
project-name |- .babelrc |- index.html |- index.js |- package.json |- style.css |- webpack.config.js |- /src + |- /images + |- logo.gif |- /js |- routes.js |- /pages |- about.vue |- app.vue |- index.vue
index.vue
<template> <div> <h1>这是首页</h1> <img src="@/images/logo.gif"> </div> </template> <script> export default {} </script> <style> h1 { text-align: center; } </style>
执行 npm run build
打包后发现图片已经成功打包进来了,可是图片的名称改变了,若是不但愿改变图片名称,能够给 file-loader 配置参数
webpack.config.js
module.exports = { // ... module: { rules: [ { test: /\.(png|jpe?g|gif)$/i, loader: 'file-loader', options: { name: 'images/[name].[ext]' } } ] } }
使用 cssnano 压缩 CSS,该插件属于 PostCSS 生态系统,因此须要同时安装 postcss-loader
执行 npm install --save-dev cssnano postcss-loader
建立一个 postcss.config.js 文件,这是 PostCSS 的配置文件,相关配置都写在这里面
project
project-name |- .babelrc |- index.html |- index.js |- package.json + |- postcss.config.js |- style.css |- webpack.config.js ...
postcss.config.js
module.exports = { plugins: { 'cssnano': { safe: true } } }
webpack.config.js
module.exports = { // ... module: { rules: [ { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader }, { loader: 'css-loader' }, { loader: 'postcss-loader' } ] } ] } }
这里使用 postcss-preset-env 来预处理 CSS(也能够选择使用 Sass 或者 Less 等)
执行 npm install --save-dev postcss-preset-env
该插件也属于 PostCSS 生态系统,直接在 postcss.config.js 里增长配置便可
postcss.config.js
module.exports = { plugins: { + 'postcss-preset-env': {}, 'cssnano': { + autoprefixer: false, // 这里两个插件都包含了 autoprefixer,只执行其中一个就行 safe: true } } }
使用 Axios 发送 HTTP 请求,Axios 基于 Promise,因此同时安装 es6-promise polyfill
执行 npm install --save axios es6-promise
index.js
+ import 'es6-promise/auto' + import axios from 'axios' // ...
在项目中发送一个请求
index.js
import 'es6-promise/auto' import axios from 'axios' + axios.post('/login') // ...
运行后这个请求明显会返回一个 404,那么如何让它返回有效的数据呢,在 webpack.config.js 里配置 devServer
参数
webpack.config.js
module.exports = { // ... devServer: { + before(app, server) { + app.post('/login', (req, res) => { + res.json({success: true}) + }) + }, compress: true, port: 8080 } }
从新启动后,就能够看到请求 /login 地址返回了数据 {"success": true}
,这样就能够在本地调试接口了
固然,全部接口都这样写未免麻烦,能够用 proxy
参数将请求接口代理到其它地址去
webpack.config.js
module.exports = { // ... devServer: { before(app, server) { app.post('/login', (req, res) => { res.json({success: true}) }) }, + proxy: { + '/api': { + target: 'http://localhost:3000' + } + }, compress: true, port: 8080 } }
这时,例如请求 /api/posts 实际上会被代理到 http://localhost:3000/api/posts
配置 mode 参数
webpack.config.js
module.exports = { mode: 'production' // ... }
production
和 development
两种 mode 参数很明显,production
用于发布,development
用于开发,具体有什么区别,看这里 Click here
执行 npm run build
便可打包,打包后生成的文件都在 dist 目录中