从零开始使用 Webpack 搭建 Vue 开发环境
创建项目
先创建一个空目录,在该目录打开命令行,执行 npm init
命令创建一个项目(无法执行 npm 命令?需要先安装 node),这个过程会提示输入一些内容,随意输入就行,完成后会自动生成一个 package.json 文件,里面包含刚才输入的内容
创建一个 index.html 页面,由于使用的是 vue 开发单页应用,所以通常一个 html 文件就够了,内容也很简单,就一个 div#app
project
project-name + |- index.html |- package.json
index.html
<!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>
project
project-name |- index.html + |- index.js |- package.json + |- webpack.config.js
创建一个 index.js 作为项目的主入口,创建一个 webpack.config.js 文件作为 webpack 的配置文件,内容如下
webpack.config.js
'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
安装 webpack
在 package.json 文件对应的 scripts
处写入命令
package.json
{ "scripts": { + "build": "webpack" } }
执行 npm run build
即可完成打包,打包成功后的文件放在 dist 目录里面(这是由配置文件自定义的),目前打包出来的只有一个 index.js 文件
启动本地服务
使用 来启动本地服务,方便开发以及本地调试
执行 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 文件
使用 来生成 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' }) ] }
安装 vue
执行 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 })
配置 babel
由于前面的代码使用了 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
项目中肯定会用到 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 文件,所以需要 来处理
执行 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 单独提取出来,使用 插件来提取 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` }) ] }
处理图片
项目中如果有用到图片需要 来处理
执行 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]' } } ] } }
压缩 css
使用 压缩 css,该插件属于 postcss 生态系统,所以需要同时安装
执行 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' } ] } ] } }
css 预处理
这里使用 来预处理 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 } } }
http 请求
使用 axios 发送 http 请求,axios 基于 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 目录中
更多
上一篇: day009--python文件操作