和《从零搭建 vue2 vue-router2 webpack3 工程》同样,以新手视角,详细介绍各个步骤内容,不深刻讲步骤涉及的原理,主要介绍如何操做。javascript
文中示例工程地址:https://github.com/qinshenxue/vue2-vue-router2-webpack4。css
新建工程目录 vue2-vue-router2-webpack4,在目录下执行npm init -y
来建立一个 package.json,在 package.json 中先添加如下必要模块:html
{
"name": "vue2-vue-router2-webpack4", "version": "1.0.0", "devDependencies": { "vue": "^2.5.17", "vue-loader": "^15.4.1", "vue-router": "^3.0.1", "vue-template-compiler": "^2.5.17", "webpack": "^4.17.1", "webpack-cli": "^3.1.0", "webpack-dev-server": "^3.1.6" } }
Webpack 4 开始,命令行工具(CLI)须要单独安装。vue
新建目录结构以下,新增的目录及文件先空着,后面的步骤会说明添加什么内容。java
vue2-vue-router2-webpack4 |-- package.json |-- index.html // 访问首页 |-- webpack.config.js // Webpack 配置文件 |-- src |-- views // Vue 页面目录 |-- main.js // 入口起点 |-- router.js // vue-router 配置 |-- app.vue // Vue 根组件
Webpack 默认读取 webpack.config.js,文件名不能随便改,其中 entry 是必须配置的,构建时,output.filename是必需的。node
module.exports = { mode: "development", entry: './src/main.js', output: { path: __dirname + '/dist', publicPath: '/static/', filename: 'build.js' } }
Webpack 4 增长了 mode 配置项,支持配置
"production" | "development" | "none"
三个可选配置,默认为"production"
。android
mode 的做用能够简单归纳为把各个环境经常使用的配置缩减为一个配置。webpack
配置为 development 背后其实是包含了以下配置。git
module.exports = { devtool: 'eval', plugins: [ new webpack.NamedModulesPlugin(), new webpack.NamedChunksPlugin(), new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }) // 设置环境变量为 '"development"' ] }
配置为 production 背后其实是包含了以下配置。github
module.exports = { mode: 'production', plugins: [ new UglifyJsPlugin(/* ... */), // 压缩 // 设置环境变量为 '"production"' new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), // 做用域提高 new webpack.optimize.ModuleConcatenationPlugin(), new webpack.NoEmitOnErrorsPlugin() ] }
webpack-dev-server 不须要配置文件,直接使用其 CLI 提供的命令便可。
"scripts": { "dev": "webpack-dev-server --hot --open" }
在 index.html 中添加测试代码,引入打包后的 JavaScript 文件。
<body> Hello, Webpack 4. <br> <script src="/static/build.js"></script> </body>
在 main.js 中添加测试代码。
// main.js document.write('来自 main.js 的问候!')
执行下面的命令来安装依赖模块并启动本地服务器。
# 安装依赖模块 npm install # 启动本地服务器 npm run dev
启动后浏览器会自动打开http://localhost:8080
,若是控制台没有报错,页面正确显示 main.js 和 index.html 的内容,改动 main.js 后浏览器会自动刷新,则表示配置没问题。
在 views 目录下新建 index.vue。
<template> <div> 这是{{page}}页面 </div> </template> <script> export default { data: function () { return { page: 'index' } } } </script>
将 vue-router 实例化传入的参数提取到 router.js 做为路由配置文件。
import index from './views/index.vue' export default { routes: [ { path: '/index', component: index } ] }
在 index.html 添加 Vue 根实例的挂载元素。
<body> <div id="app"></div> <script src="/static/build.js"></script> </body>
在 main.js 完成路由配置、初始化 Vue 实例。
import Vue from "vue" import VueRouter from "vue-router" import App from "./app.vue" import routerConfig from "./router" Vue.use(VueRouter) const router = new VueRouter(routerConfig) new Vue({ el: "#app", router: router, render: h => h(App) })
在根组件 app.vue 中添加路由连接、路由视图组件。
<template> <div> <div> <router-link to="/index">Home</router-link> </div> <div> <router-view></router-view> </div> </div> </template>
配置 .vue 文件对应的 loader。
const VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { mode: "development", entry: './src/main.js', output: { path: __dirname + '/dist', publicPath: '/static/', filename: 'build.js' }, module: { rules: [{ test: /\.vue$/, use: ["vue-loader"] }] }, plugins: [ new VueLoaderPlugin() ] }
vue-loader 从 v15.0.0 开始,配置须要引入
vue-loader/lib/plugin
,并在 plugins 中初始化。详细请参考官方文档 https://vue-loader.vuejs.org/zh/guide/#vue-cli。
上面完成了访问一个页面所须要的步骤,接下来能够启动本地服务器(npm run dev
)来测试可否正常访问/index。
直接在 .vue 文件中使用 CSS 会提示You may need an appropriate loader to handle this file type.
,CSS 对应的 loader 为css-loader
。
npm install css-loader -D
vue-loader v15.0.0 以前不须要配置 loader 就能够在 vue 文件中使用 CSS,须要用 import 或 require CSS 文件时才须要配置 loader,而 v15.0.0 以后均须要本身配置 loader 才不会报错。
{
test: /\.css$/, use: ["vue-style-loader", "css-loader"] }
import './assets/css/style.css'
vue-style-loader 是 vue-loader 的 dependencies,所以不须要再本身安装,css-loader 是 vue-loader 的 peerDependencies,须要本身安装。
根据须要安装预处理语言模块及对应的 loader。
# less npm install less less-loader -D # sass npm install node-sass sass-loader -D # stylus npm install stylus stylus-loader -D
node-sass 安装慢的解决办法:
npm set disturl https://npm.taobao.org/dist
npm set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass
各类预处理语言的 loader 配置。
// less { test: /\.less$/, use: ["vue-style-loader", "css-loader", "less-loader"] } // sass { test: /\.s[ac]ss$/, use: ["vue-style-loader", "css-loader", "sass-loader"] } // stylus { test: /\.styl$/, use: ["vue-style-loader", "css-loader", "stylus-loader"] }
使用示例。
<style lang="less"> .view{ color:red; } </style> <style lang="sass"> .view{ border-bottom:1px solid #ddd; } </style> <style lang="styl"> .view margin-top:20px; </style>
安装图片及图标字体依赖的 loader。
npm install url-loader file-loader -D
配置图片及图标字体对应的 loader。
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use: [{ loader: "url-loader", options: { limit: 10000, name: 'images/[name].[hash:7].[ext]' // 将图片都放入 images 文件夹下,[hash:7]防缓存 } }] }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, use: [{ loader: "url-loader", options: { limit: 10000, name: 'fonts/[name].[hash:7].[ext]' // 将字体放入 fonts 文件夹下 } }] }
使用 Webpack CLI 提供的命令构建。点击查看 Webpack 命令参数
"build": "webpack --progress"
执行npm run build
开始构建,完成后,能够看到工程目录下多了 dist 目录,里面包含了打包后的 JavaScript 文件、图片、图标字体文件,可是打包后的 JavaScript 文件没有被压缩,里面还包含了 CSS 代码,语法也没有被转换成 ES5,这些工做就须要使用 Webpack 插件来完成。
Babel 7 正式版已经发布,较 Babel 6 变化以下:
安装 Babel。
npm install babel-loader @babel/core @babel/cli @babel/preset-env -D
增长 Babel 配置文件 babel.config.js。
const presets = [ ["@babel/env", { targets: { ie: "9" }, modules: false }] ] module.exports = { presets }
配置 babel-loader。
{
test: /\.js$/, exclude: /node_modules/, use: ["babel-loader"] }
上面提到过, Webpack 4 新增的 mode 配置项配置为'production'
时,已经包含了压缩插件(new UglifyJsPlugin()
),所以不用再额外配置。
extract-text-webpack-plugin 不支持 Webpack 4,提取 CSS 改用 mini-css-extract-plugin
npm i mini-css-extract-plugin -D
调整 Webpack 配置以下。
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { //... module: { rules: [{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.less$/, use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"] }, { test: /\.s[ac]ss$/, use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"] }, { test: /\.styl$/, use: [MiniCssExtractPlugin.loader, "css-loader", "stylus-loader"] } //... ] }, plugins: [ // ... new MiniCssExtractPlugin({ filename: 'css/style.css' }) ] }
vue-loader 不须要单独配置就能够提取 vue 文件中的 CSS。在 index.html 中引入 CSS 文件便可看到效果。
安装 postcss-loader 及 PostCSS 插件。
npm install postcss-loader autoprefixer cssnano -D
loader 配置调整以下。
{
test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader", 'postcss-loader'] }, { test: /\.less$/, use: [MiniCssExtractPlugin.loader, "css-loader", 'postcss-loader', "less-loader"] }, { test: /\.s[ac]ss$/, use: [MiniCssExtractPlugin.loader, "css-loader", 'postcss-loader', "sass-loader"] }, { test: /\.styl$/, use: [MiniCssExtractPlugin.loader, "css-loader", 'postcss-loader', "stylus-loader"] }
postcss-loader 要放在 css-loader 后,CSS 预处理语言的 loader 以前。
新增 postcss-loader 须要配置文件 postcss.config.js,引入插件。
module.exports = { plugins: [ require('autoprefixer')({ browsers: ['android > 4'] }), require('cssnano') ] }
PostCSS 插件分类搜索网站:http://postcss.parts/
手动引入打包后的 JavaScript 和 CSS 比较麻烦,使用 html-webpack-plugin 插件生成的页面自动引入了打包后的资源。
npm install html-webpack-plugin -D
初始化插件。
var HtmlWebpackPlugin = require('html-webpack-plugin') plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.tpl.html' }) ]
index.tpl.html
<html> <head> ... </head> <body> <div id="app"></div> </body> </html>
将开发和生产配置文件分离,方便增长各个环境下的个性配置。Webpack 官方文档中也详细阐述了如何为多环境增长配置文件,基本思路以下。
webpack.base.config.js 内容以下。
const VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { entry: './src/main.js', output: { filename: 'js/[name].js' }, module: { rules: [{ test: /\.vue$/, use: ["vue-loader"] }, { test: /\.js$/, exclude: /node_modules/, use: ["babel-loader"] }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use: [{ loader: "url-loader", options: { limit: 10000, name: 'images/[name].[hash:7].[ext]' // 将图片都放入 images 文件夹下,[hash:7]防缓存 } }] }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, use: [{ loader: "url-loader", options: { limit: 10000, name: 'fonts/[name].[hash:7].[ext]' // 将字体放入 fonts 文件夹下 } }] } ] }, plugins: [ new VueLoaderPlugin() ] }
开发环境通常不配置提取 CSS,而生产环境须要配置,所以上面的基础配置不包含 CSS loader。path 和 publicPath 在开发和生产环境下通常不一样,所以也不包含在基础配置中。
开发配置文件(webpack.dev.config.js)内容以下内容以下。
const merge = require("webpack-merge") const HtmlWebpackPlugin = require("html-webpack-plugin") const baseWebpackConfig = require("./webpack.base.config") module.exports = merge(baseWebpackConfig, { mode: 'development', output: { publicPath: "/" }, module: { rules: [{ test: /\.css$/, use: ["vue-style-loader", "css-loader", 'postcss-loader'] }, { test: /\.less$/, use: ["vue-style-loader", "css-loader", 'postcss-loader', "less-loader"] }, { test: /\.s[ac]ss$/, use: ["vue-style-loader", "css-loader", 'postcss-loader', "sass-loader"] }, { test: /\.styl$/, use: ["vue-style-loader", "css-loader", 'postcss-loader', "stylus-loader"] }] }, plugins: [ new HtmlWebpackPlugin({ filename: "index.html", template: "index.tpl.html" }) ] })
生产配置文件(webpack.prod.config.js)内容以下。
const merge = require("webpack-merge") const HtmlWebpackPlugin = require("html-webpack-plugin") const MiniCssExtractPlugin = require("mini-css-extract-plugin") const baseWebpackConfig = require("./webpack.base.config") const path = require('path') module.exports = merge(baseWebpackConfig, { mode: 'production', output: { path: path.resolve(__dirname, '../dist') publicPath: "/static/" }, module: { rules: [{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader", 'postcss-loader'] }, { test: /\.less$/, use: [MiniCssExtractPlugin.loader, "css-loader", 'postcss-loader', "less-loader"] }, { test: /\.s[ac]ss$/, use: [MiniCssExtractPlugin.loader, "css-loader", 'postcss-loader', "sass-loader"] }, { test: /\.styl$/, use: [MiniCssExtractPlugin.loader, "css-loader", 'postcss-loader', "stylus-loader"] }] }, plugins: [ new MiniCssExtractPlugin({ filename: 'css/style.css' }), new HtmlWebpackPlugin({ filename: "index.html", template: "index.tpl.html" }) ] })
对应在 package.json 中添加开发和生产构建的命令以下。
"scripts": { "dev": "webpack-dev-server --progress --hot --open --config build/webpack.dev.config.js", "build": "webpack --progress --config build/webpack.prod.config.js", }
本文地址: https://www.qinshenxue.com/article/vue2-vue-router2-webpack4.html