Vue和Webpack、loader、plugin详解
(一) 安装Webpack安装webpack首先要安装Node.js(版本大于9.0),Node.js自带了软件包管理工具npm查看自己的node版本: node -v全局安装webpack(版本号为3.6.0,因为vue cli2依赖该版本)//检查自己是否安装了webpackwebpack --version//如果没有安装则运行下边代码,梯子安装更快捷npm install webpack@
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。
(一) 安装Webpack
-
安装webpack首先要安装Node.js(版本大于9.0),Node.js自带了软件包管理工具npm
-
查看自己的node版本: node -v
-
全局安装webpack(版本号为3.6.0,因为vue cli2依赖该版本)(一般不建议全局安装)(如果想安装最新版本的webpack则不需要加上 @3.6.0)
#检查自己是否安装了webpack webpack --version #如果没有安装则运行下边代码,梯子安装更快捷 npm install webpack@3.6.0 webpack-cli -g
-
局部安装webpack(如果想安装最新版本的webpack则不需要加上 @3.6.0)
#进入到对应的项目文件后运行如下代码 npm install webpack@3.6.0 webpack-cli --save-dev
(二) Webpack的起步
-
该部分最终的目录结构
-
在项目文件夹中的控制台中执行如下代码,创建 package.json 文件,用于管理项目的信息、库依赖等
# 也可以使用npm init -y ,将不会出现图片所示的选项 npm init
-
在项目文件夹中的控制台中运行如下代码安装 webpack, 安装后在项目文件夹中将会生成一个 node_modules 文件夹
npm install webpack@3.6.0 webpack-cli -D
-
在src文件夹中 新建三个文件
-
[1]. index.js
// 1.使用commonjs的模块化规范 导入common-js-test.js文件中的 job、userTool 变量 与 getJob、sum 方法 const { job, userTool, getJob, sum } = require("./common-js-test.js"); console.log('job: ' + job); console.log('userTool: ' + userTool); console.log('getJob:' + getJob()); console.log('sum:' + sum()); // 2.使用ES6的模块化的规范 导入 module-test.js 文件中的 age 变量 与 add 、getAge方法 // module-test.js 文件中未命名的方法,在这里将被命名为 mulNum // 如果 module-test.js 文件 只导出 一个未命名的方法,则可以使用: import mulNum from './module-test.js', 来导出该方法 import { age, add, getAge, default as mulNum } from "./module-test.js"; console.log('age:' + age); console.log('add:' + add(5, 5)); console.log('mulNum: ' + mulNum(8, 5));
-
[2].common-js-test.js
// commonjs 方式导出变量与方法 const job = '程序员' const getJob = function () { return '工作为:' + job } module.exports = { userTool: 'webpack', // 也可以在这里定义 userTool 变量 sum: function(){ return 1 + 1} , // 也可以在这里定义 sum 方法 job, getJob: getJob }
-
[3].module-test.js
//写法1: 导出 age 变量 与 add 方法,可以同时导出多个 const age = 32 const add = function (a, b) { return a + b } export { age, add } //写法2:导出一个不命名的方法,导入时进行命名,只能导出自己 //同一个文件中只能有一个 default export default function (a, b) { return a * b } //写法3:导出 getAge 方法,只能导出自己 export const getAge = function (a, b) { return '获取age:' + age }
-
在控制台中进入到在项目所在的目录下(即index.html所在的目录),然后使用如下命令,在 dist 文件中生成 main.js
#与下边命令等价: #高版本webpack使用:npx webpack --entry ./src/index.js --output-path ./dist --mode=development #低版本webpack使用: npx webpack --entry ./src/index.js ./dist/index.js
-
在 index.html 中引入 main.js 文件
<script src="dist/main.js"></script>
-
在浏览器中打开index.html文件即可看到运行结果。
(三) Webpack的配置
[1].webpack.config.js配置
最终的文件夹结构
- 一直在控制台中输入
npx webpack 源文件 目标文件
命令来打包js文件,会觉得不方便,这时可以配置webpack 来方便使用。 - 在项目根目录下创建一个 webpack.config.js 文件 (名字固定) ,设置本项目的配置文件, 如果此时直接在终端中输入“webpack”,会报一个路径不对的错误。所以需要使用node来获取路径。
//使用node获取项目路径,require("path")中的path会从node的包里边找,所以要创建node包 const path = require("path"); module.exports = { //对应的入口 entry: './src/index.js', //对应的出口 output: { //path要写为绝对路径 path: path.resolve(__dirname, 'dist'), //__dirname是node保存的当前文件夹的绝对路径 filename: 'bundle.js' }, }
- 在控制台中输入
npx webpack
执行打包,将在 dist 文件夹中就会生成 bundle.js文件。
[2].package.json配置
-
将
npx webpack
命令映射到 npm run build。 -
在package.json文件中有一个“scripts”属性,可以映射脚本。在“scripts”中添加"build": “webpack”
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" },
-
在终端中输入如下代码,就可以实现webpack功能。
npm run build
-
在“scripts”中的代码执行时,优先使用的是当前项目配置的webpack,然后没找到时才使用全局配置的webpack。
(四) webpack中loader的使用
- 在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等等。对于webpack本身的能力来说,对于这些转化是不支持的。给webpack扩展对应的loader就可以啦。
- https://www.webpackjs.com/loaders/#%E6%A0%B7%E5%BC%8F
[1].css-loader加载css文件
- style-loader 将模块的导出作为样式添加到 DOM 中
- css-loader只负责将css文件进行加载。
- 文件结构,其中main.js负责引入info.js、mathUtils.js和common.css文件,在main.js中引入css文件使用 require(“./css/common.css”); 代码
-
安装style-loader
npm install style-loader --save-dev
-
安装css-loader
npm install --save-dev css-loader
-
在入口文件中引入css文件,(这里还是在main.js文件中引入,main.js作为src的入口文件)
require("./css/common.css");
-
配置webpack.config.js 文件,为module.exports 添加module属性。
module.exports = { module: { rules: [ { test: /\.css$/, //系统读取use的值时是从右向左读 use: ['style-loader','css-loader'] } ] } }
-
开始打包
进入到项目根目录,然后执行如下代码webpack ./src/main.js ./dis/bundle.js
[2].url-loader加载img
- 在css文件中如果使用到了图片需要添加url-loader
-
安装url-loader
npm install --save-dev url-loader
-
配置webpack.config.js文件
module.exports = { module: { rules: [ //这个是css-loader的配置 { test: /\.css$/, use: ['style-loader','css-loader' ] }, //这个是url-loader的配置 { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { //当加载的图片大小 小于limit时,会将图片编译成base64字符串形式 //如果大于limit时,会需要一个file-loader,直接安装file-loader就行,不需要配置 limit: 8192 } } ] } ] } }
-
如果加载的图片的大小 大于设置的limit时
-
(1). 需要一个file-loader,直接安装file-loader就行,不需要配置。然后就会在导出文件的文件夹中有这个图片。此时图片的命名是一个32位的hash值。
npm install --save-dev file-loader
-
(2). 这时虽然有这个图片但是生成后的页面中找不到该文件,这时需要设置webpack.config.js文件。在output中添加publicPath值为导出的文件夹
module.exports = { //对应的入口 entry: './src/main.js', //对应的出口 output: { //path要写为绝对路径 path: path.resolve(__dirname, 'dist'), //__dirname是node保存的当前文件夹的绝对路径 filename: 'bundle.js', publicPath: "dist/" //**** 添加这个 ****** }, module: { rules: [ { test: /\.css$/, use: ['style-loader','css-loader' ] }, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192 } } ] } ] } }
-
(3). 如果不希望生成一个随机数的图片名字可以在webpack.config.js文件夹中的url-loader模块下的options属性下,添加name选项。
use: [ { loader: 'url-loader', options: { limit: 8192, //路径:因为已经设置了publicPath为:dist/,所以会在dist文件夹下创建路径中的文件夹 //name要带中括号,这样就会将[name]当做一个变量,变量的值就是原来的图片的名字 //[hash:8]取hash值的前八位 //[ext]后缀 name: "路径/[name].[hash:8].[ext]" }, } ]
- 开始打包
[3].babel-loader将ES6转为ES5
https://www.webpackjs.com/loaders/babel-loader/
-
将ES6的语法转为ES5,需要使用babel,在webpack中直接使用如下代码。
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
-
配置webpack.config.js文件
module: { rules: [ { test: /\.js$/, //排除mode_modules、bower_components文件夹 exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['es2015'] } } } ] }
-
开始打包
(五) Webpack中配置vue
-
安装vue,因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖所以使用的--save而不是--save-dev。
进入到项目根目录后执行下边的代码
npm install vue --save
-
直接使用如下代码进行vue开发,会报一个如下的错误
bundle.js:961 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
//1. 引入vue import Vue from 'Vue' //2.开始写代码 const app = new Vue({ el:"#app", data: { message: "hello world!" } });
-
在webpack.config.js中module.exports配置一个属性resolve。(进行这一步的前提是进行了项目的webpack的安装,即局部安装看(一)节有)
module.exports = { entry: './src/main.js', output: { ... }, module: { ... }, resolve: { alias:{ //含义:当js文件需要引入Vue时,会告诉js去node_modules/vue/dist/vue.esm.js路径下寻找 //node_modules是局部的webpack文件夹 //区分大小写 'Vue$': 'vue/dist/vue.esm.js' } } }
-
打包
(六) 使用template将HTML代码抽离
[1]. 使用template抽离html中的代码
-
为了避免多次修改html文件中的vue信息,可以在Vue对象中添加template属性,将需要显示在html文件中的信息添加到template属性中
-
template属性中的代码在程序执行时,会被复制到 el 属性代表的Vue区域
// 4.使用vue进行开发 import Vue from 'Vue'; const app = new Vue({ el:"#app", template:`<h2>{{message}}</h2>`, data: { message: "hello world1!" } });
[2]. 使用组件抽离template中的html代码
-
创建组件
const cpn = { template: ` <div> <h2>{{message}}</h2> <button @click="btnClick">按钮</button> </div> `, data(){ return { message: "hello world!" } }, methods:{ btnClick(){ console.log('btnClick'); } } }
-
vue引用组件
const app = new Vue({ el:"#app", template:`<cpn />`, components:{ cpn } });
-
html文件中只有
<div id="app"> </div>
-
打包
[3]. 将组件从入口文件中抽离
-
将组件从入口函数中抽离出来,放在src文件夹的vue文件夹中,使用export default命令,为模块指定默认输出。
export default { template: ` <div> <h2>{{message}}</h2> <button @click="btnClick">按钮</button> </div> `, data(){ return { message: "hello world!" } }, methods:{ btnClick(){ console.log('btnClick1'); } } }
-
在入口文件中引入组件,并命名为cpn
import cpn from './vue/app.js'
(七) 使用.vue文件封装vue
[1]. 封装一个vue文件
-
创建一个app.vue文件
文件结构为<template> <!-- html结构 --> </template> <script> export default { //组件代码 } </script> <style lang="stylus"> /*css样式*/ </style>
-
在template标签中放入html模板
-
在script标签中创建vue组件
-
在style标签中创建样式
<template> <div> <h2 class="myFont">{{message}}</h2> <button @click="btnClick">按钮</button> </div> </template> <script> export default { data(){ return { message: "hello world!" } }, methods:{ btnClick(){ console.log('btnClick2'); } } } </script> <style> .myFont{ color:#fff; } </style>
-
配置Vue的loader
npm install vue-loader vue-template-compiler --save-dev
-
在webpack.config.js中配置vue
module: { rules: [ { test: /\.vue$/, use: ['vue-loader'] } ] },
-
在package.json中查看“vue-loader”的版本,如果大于14.0版本需要安装一个VueLoaderPlugin的插件。
这里直接将package.json中的“vue-loader”改为"^13.0.0",然后 运行npm install
-
开始打包
[2]. vue文件再加载一个vue文件
-
在一个vue文件中引入另一个vue文件
import tpn from "./Tpn.vue"
-
注册引入的组件
export default { name: 'App', data(){ return { message: "hello world!" } }, methods:{ btnClick(){ console.log('btnClick2'); } }, components:{ tpn } }
-
使用这个组件
<template> <div> <tpn></tpn> </div> </template>
(八) plugin的使用
[1]. 打包html的plugin
当前的目录结构,发布项目是将dist文件夹中的文件放入到服务器中,但是index.html所在位置在项目的根目录下,这时也需要将index.html生成到dist文件中。
-
[1]. HtmlWebpackPlugin插件可以为我们做这些事情:
- 自动生成一个index.html文件(可以指定模板来生成)
- 将打包的js文件,自动通过script标签插入到body中
-
[2]. 安装HtmlWebpackPlugin(前提再该项目中已经安装了局部的webpack)
//安装最新版本 npm install html-webpack-plugin --save-dev
//安装3.2.0版本,因为webpack版本低,而这个的版本高会出现不兼容的问题可能打包不上,所以要使用3.2.0版本 npm install html-webpack-plugin@3.2.0 --save-dev
-
[3]. 修改webpack.config.js文件
- 添加如下代码
// 引入webpack基础组件 const webpack = require("webpack"); //引入html-webpack-plugin组件 const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = { ... plugins: [ new HtmlWebPackPlugin({ template: "index.html" }), ] }
- 添加如下代码
-
[4]. 如果webpack.config.js中有publicPath属性,要注释掉,将index.html文件中引入js、css的代码删掉
<!-- 删掉如下代码 --> <script src="dist/bundle.js"></script>
-
[5]. 打包(如果按照上边的步骤,打包还出错,要安装3.2.0版本的HtmlWebpackPlugin)
-
[6]. 会在dist文件夹中生成各种后缀的文件
[2]. js压缩的Plugin
-
在项目发布之前,我们必然需要对js等文件进行压缩处理
-
使用一个第三方的插件uglifyjs-webpack-plugin,并且版本号指定1.1.1,和CLI2保持一致。
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
-
修改webpack.config.js文件
const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = { ... plugins: [ ... new uglifyJsPlugin() ] }
-
打包
(九) 搭建本地服务器
webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。
-
它是一个单独的模块,在webpack中使用之前需要先安装它
npm install --save-dev webpack-dev-server@2.9.1
-
配置webpack.config.js文件
module.exports = { .... devServer:{ //为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist contentBase: './dist', //inline:页面实时刷新 inline: true //port:端口号,默认8080 //historyApiFallback:在SPA页面中,依赖HTML5的history模式 } }
-
因为不是全局设置的服务器,所以需要使用下面的代码来使用局部的服务器
- 第一种方案:
node_modules\.bin\webpack-dev-server
- 第二种方案:
在package.json文件中的scripts属性下添加
"scripts": {
//--open 在执行 npm run dev时可以自动打开,如果不想这样也可以不添加
"dev":"webpack-dev-server --open"
},
-
在浏览器中输入如下url即可。
localhost:8080
-
修改组件文件可以直接显示在浏览器上,可能有点慢
(十) 对webpack.config.js进行拆分
-
因为webpack.config.js文件中的配置是将开发和生产环境的配置都放在了一起,可以将其进行拆分。
-
在项目目录下新建一个build文件夹,将webpack.config.js文件进行拆分,将公共部分放在一个文件,将开发配置放在一个文件中,将生产配置放在一个文件中。
-
为了使公共文件和其他文件进行合并,需要安装webpack-merge
npm install wepack-merge --save-dev
-
例如:生产环境和公共文件的文件要进行合并在生产环境中添加如下代码。
const webpackMerge = require("webpack-merge"); //base.config就是公共配置文件 const baseConfig = require('./base.config'); module.exports = webpackMerge(baseConfig, { //生产环境所需的配置放在这里 });
-
这时就可以将项目目录下的webpack.config.js文件进行删除
-
如果直接使用"npm run build" (build是我的打包脚本名字。原型为:“build”:“webpack”) 会报一个找不到webpack.config.js文件的错误,这时需要修改package.json文件
//指定配置文件所在的位置,prod.config.js是公共配置文件和生产环境配置文件合并后生成的文件 “build”:"webpack --config ./build/prod.config.js"
-
注意在生成的prod.config.js文件时,里边的输出路径要进行更改
module.exports = { ... output: { //path要写为绝对路径 path: path.resolve(__dirname, '../dist'), //__dirname是node保存的当前文件夹的绝对路径 filename: 'bundle.js' }, }
更多推荐
所有评论(0)