通过Webpack 打包vue脚手架的初步教程
配置开发时的前端工程(vue-loader+webpack)
我们通过快捷键 ‘ctrl + ·’,也就是esc下面的小点,打开终端,先来用 npm init 来初始化项目,大家实验的时候直接敲回车就行了.
PS C:\Users\A\Desktop\reNew webpackVue> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (renew-webpackvue)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to C:\Users\A\Desktop\reNew webpackVue\package.json:
{
"name": "renew-webpackvue",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this OK? (yes)
这个时候细心的话会发现目录下面多一个package.json的文件,这个文件就是项目的配置文件。
因为我们用到了vue以及webpack,所以需要安装两个依赖包,还有段落标题中的vue-loader,这个是为了用webpack加载.vue文件,并编译成浏览器能认识的js文件,我们先来执行这样的指令,注:我们这里是demo,所以这里就不区分是否是dev-dependency了。(详情可以参考www.cnblogs.com/ayseeing/p/…)
npm i webpack vue vue-loader
PS C:\Users\A\Desktop\reNew webpackVue> npm i webpack vue vue-loader
added 118 packages, and audited 119 packages in 16s
13 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
安装完成之后可能会出现一些waring,这个waring其实就是告诉我们在安装vue-loader的同时必须要安装css-loader,这里我们想它继续安装完成就可以了。
npm WARN vue_web@1.0.0 No description npm WARN vue_web@1.0.0 No repository field.
这两个是我们项目初始化的时候由于都是回车回车,缺少一些描述,无需关心。
npm WARN optional SKIPPING OPTIONAL npm WARN notsup SKIPPING OPTIONAL
这两个是告诉我们项目初始化时候哪些是可选择安装的,哪些是可以不安装的,继续执行
npm i css-loader
PS C:\Users\A\Desktop\reNew webpackVue> npm i css-loader
up to date, audited 119 packages in 2s
13 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
好,到这里,我们项目的大概的初始化工作就完成了。接下来我们就基于这样的目录,填充一下更丰富的细节。
我们在工程目录下新建一个src文件夹用来存放源文件,并新建一个app.vue的文件:
app.vue代码如下:
<template>
<div id="text">
{{text}}
</div>
</template>
<script>
export default {
data() {
return {
text: 'hello world'
}
}
}
</script>
<style>
#text {
color: blueviolet;
font-family: fangsong;
}
</style>
大家都知道,浏览器其实只能够识别一些简单的文件,像js,css,html,img,font,但是如何让浏览器识别vue文件呢?
webpack配置
1. 输入输出
到这其实我们应该有一些认知了,webpack其实就是一个帮我们打包的工具。接下来我们在工程目录下新建一个webpack.config.js文件。
大家都知道,webpack是用来打包的工具 所以,接下来我们在新建的webpack.config.js里面做文章,配置webpack的入口和出口,让浏览器去访问,让webpack去打包并输出。
在src目录下新建一个index.js的文件作文工程的入口文件。
然后我们在index.js里面写一些内容,代码中我都做了注释,大家应该一眼就能看懂
index.js:
//这是工程的入口文件
import Vue from 'vue';
import App from './app.vue';
const root = document.createElement('div')
document.body.appendChild(root)
//mount就是讲我们的App挂载到root这样一个根节点中去
new Vue({
render: (h) => h(App)
}).$mount(root)
我们这时候发现,浏览器要想运行这段代码,那是不可能的,因为浏览器不认识vue,更不认识new Vue,所以webpack要登场了。我们在webpack.config.js里配上entry入口和out出口,表示webpack文件会将将entry路径下的文件,打包到out的路径,
具体如下:
webpack.config.js:
const path = require("path");//nodejs里面的基本包,用来处理路径
//__dirname表示文件相对于工程的路径
module.exports ={
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
}
}
这里代码就不多说了,都有注释,这里卖个关子,也是经常会发生的场景,就是这里的join和resolve这两个函数的用法和区别,最好去官网看一下说明,直通车webpack.js.org/,英文不好的同学可以去…
好上面的代码就是做了这样一件事,将src下的index.js文件以js的形式打包到dist目录下的bundle.js中去。大家有疑问了,这两个目录我还没有新建呢!没有关系out属性中定义的路径如果没有的话,webpack会自动创建的,我们需要做的是就是新建src目录并添加index.js文件。那这个动作我们已经新建完成了,不记得的同学返回文章内容再看看。
这时候我们打开package.json文件添加一句:
"build": "webpack --config webpack.config.js"
很多有经验的同学应该都用过npm run build 这段指令,之后webpack帮我们干的一些事情,执行我们新建的webpack.config.js文件。注意:这里我们使用webpack来执行指令,同样可以在终端执行这段指令,但是我们要清楚在终端直接执行build后面的指令会出现一个问题,如我们在终端执行该指令,意味着使用的是全局的webpack,但是我们写在package.json文件下的话,意味着执行工程下面的局部wepackage,全局和局部可能会版本不一样,所以为了避免不必要的麻烦,我们在package.json文件下执行,也就是说使用的局部的webpack来打包。
好到这里,我们编译打包输入输出的相关配置已经完成,我们先执行一下:npm run build。可能有经验的小伙伴会发现还有一些配置没有完成,没关系,我们一步步来,带着错误把问题一个一个解决。
npm run build
PS C:\Users\A\Desktop\reNew webpackVue> npm run build
> renew-webpackvue@1.0.0 build
> webpack --config webpack.config.js
CLI for webpack must be installed.
webpack-cli (https://github.com/webpack/webpack-cli)
We will use "npm" to install the CLI via "npm install -D webpack-cli".
Do you want to install 'webpack-cli' (yes/no): yes
由于我使用的是webpack4,所以这里必须要安装一下cli。这里有人就问了,不是不用cli的嘛,怎么要安装这个包。如果你有这样的想法,证明你有自己用过cli搭建过vue项目框架的一些经验。我们知道用cli脚手架搭建出来的项目结构应该是这样的:
该图来源于网络,我们这里安装这个cli包是因为webpack4之后强制要求安装的,但是我们并没有通过该工具来初始化整个工程,所以建出来的目录也是不一样的,所以大家仔细想想就明白了。好了,接下来直接yes就可以,安装完成之后,再执行一下 npm run build,有些不需要再执行,但没有关系,反正都会报错:
这个错误呢就是告诉我们,需要为app.vue这个文件声明一个loader,因为webpack只支持js类型的文件,像这种vue文件是不支持的,所以我们要使用一些工具,来帮助它认识超出它理解范畴的语法。接下来便到了我们的module环节。
2. Module
由于webpack存在这样的一个限制,我们就需要来使用一些工具,我们在webpack.config.js里添加module配置项
webpack.config.js:
const path = require("path");//nodejs里面的基本包,用来处理路径
//__dirname表示文件相对于工程的路径
module.exports ={
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [
{//通过vue-loader来识别以vue结尾的文件
test: /.vue$/,
loader: 'vue-loader'
}
]
}
}
好添加完成之后,再次执行 npm run build 指令。
好,又报错了,这时候的错误是告诉我使用vue-loader的方式不正确。Vue-loader在15.*之后的版本都是 vue-loader的使用都是需要伴生 VueLoaderPlugin的,所以我们这里再来修改一下。这里会使用plugin属性,不了解的同学可以先跳过,也可以去官网查看一下这个属性的作用,这里我就先不介绍了。我们在package.config.js文件中添加VueLoaderPlugin,代码如下:
const path = require("path");//nodejs里面的基本包,用来处理路径
const VueLoaderPlugin = require('vue-loader/lib/plugin');
//__dirname表示文件相对于工程的路径
module.exports ={
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
plugins: [
// make sure to include the plugin for the magic
new VueLoaderPlugin()
],
mode:'none',
module: {
rules: [
{//通过vue-loader来识别以vue结尾的文件
test: /.vue$/,
loader: 'vue-loader'
}
]
}
}
再次执行一次 npm run build
还会报错,哈哈,到这有人会抱怨啦,是不是没玩没了啦。不用担心,保证这个问题解决完之后就可以啦。先看错误信息
不知道大家还记不记的我在app.vue
文件中用“style标签嵌入”的方的式写css样式了
但是webpack并没有处理css的能力
,所以我们还需要在moudle添加rules配置项,如下
const path = require("path");//nodejs里面的基本包,用来处理路径
const VueLoaderPlugin = require('vue-loader/lib/plugin');
//__dirname表示文件相对于工程的路径
module.exports ={
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
plugins: [
// make sure to include the plugin for the magic
new VueLoaderPlugin()
],
mode:'none',
module: {
rules: [
{//通过vue-loader来识别以vue结尾的文件
test: /.vue$/,
loader: 'vue-loader'
},
{//通过vue-loader来识别以vue结尾的文件
test: /.css$/,
//css的处理方式不同,有嵌入在页面style标签里的,有从外部文件引入的,我们这里用use来声明
use: [
'style-loader',//接受潜在页面内部的style标签的文件。
'css-loader'
]
}
]
}
}
好了,别忘了执行一下,
npm i style-loader
因为之前没有安装过这个包,否则又要报错了。这部分属于配置静态资源的部分了,这里遇到了问题,就先介绍了。我们最后执行一下 npm run build
指令,不出意外的话,应该是这样的:
webpack配置项目加载各种静态资源及css预处理器
1. 静态资源
上一张我们详细使用了webpack加载并打包vue文件,以及最后处理的css文件,就针对静态资源这块,我们可以稍微更详细地了解一下。
好,在上一张的末尾,我们接触了css样式加载,我们稍微复习一下,大家也可以回头在巩固一下。
这里用了use属性而不是loader属性,是因为我们处理css文件的方式有多种,所以这里出多种方式的css加载需要用到use属性,所以这里用到了use,style-loader也就是处理html文件内部的style标签内的css样式,也就是我们俗称的内联,css-loader处理的是从文件外部引入的css文件,这里大家简单了解一下。
然后我们的图片怎么做呢?我相信大家举一反三的能力比我强多了,我们加载图片用到的loader叫‘url-loader’,它的作用是将我们的图片转换成一个base64的字串存放于我们打包生成的js里面,而不是重新生成一个文件。对于一些小的文件,几kb的文件可以帮助我们减少过多的http请求。那么url-loader其实封装了我们的file-loader,file-loader其实是将文件进行处理后换个名字存放于另一个地方。那么我们先看下配置:
const path = require("path");//nodejs里面的基本包,用来处理路径
const VueLoaderPlugin = require('vue-loader/lib/plugin');
//__dirname表示文件相对于工程的路径
module.exports ={
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
plugins: [
// make sure to include the plugin for the magic
new VueLoaderPlugin()
],
mode:'none',
module: {
rules: [
{//通过vue-loader来识别以vue结尾的文件,正则表达式中的点需要转义
test: /\.vue$/,
loader: 'vue-loader'
},
{//通过vue-loader来识别以vue结尾的文件
test: /\.css$/,
//css的处理方式不同,有嵌入在页面style标签里的,有从外部文件引入的,我们这里用use来声明
use: [
'style-loader',//接受潜在页面内部的style标签的文件。
'css-loader'
]
},
{//处理图片文件
test: /\.(gif|jpg|jpeg|png|svg)$/ ,
use: [
{
loader: 'url-loader',
options: {
limit: 1024,
name: '[name]-aaa.[ext]'
}
},
]
}
]
}
}
我们这里同样使用的use属性,不同的是数组里面使用的对象,因为我们对图片还需要进行一些更细化的配置,像图片的大小(limit),文件名称(name)有时都是需要进行配置的,所以这里使用了对象。下面呢,我们将使用到的loader安装一下。
npm i url-loader file-loader
我们安装完成了之后,所有的包是可以通过import来使用的。
接下来我们介绍一下图片的loader,新建一个assets目录,然后放几张图片进去,并同时新建一个styles目录新建一个test样式
图片大家可以自行下载,css就简单的给body设置了样式:
test.css:
body{
color: red;
background-image: url('../images/logo.png');
}
并且将我们项目的入口文件添加几行代码:
//这是工程的入口文件
import Vue from 'vue';
import App from './app.vue';
import './assets/styles/test.css';
import './assets/images/vue.png'
const root = document.createElement('div')
document.body.appendChild(root)
//mount就是讲我们的App挂载到root这样一个根节点中去
new Vue({
render: (h) => h(App)
}).$mount(root)
好,我们现在执行一下npm run build 指令,可以看到webpack将图片打包成base64字串存放于js中,并且重新生成了新的文件
配置信息的参数“limit=1024”表示将所有小于1kb的图片都转为base64形式,而我们的图片的大小:
都超过了1KB,webpack表示不是我的锅,我不背...
我们将limit稍微改大一点设置100k,按照理论小一点的图片应该会被处理成base64的图片。我们再次执行一下npm run build
2. css预处理
我们经常听到过 sass less style-component这些比较火热的css预处理器,那这些我们webpack能不能处理呢?答案是肯定的。
这里我给大家推荐一款预处理器-stylus,大家多多少少听过或者使用过。我们新增一个配置项,注意:我们这里新增了stylus-loader,所以需要将这个安装包执安装,由于stylus-loader这个包依赖于stylus这个包,所以我们这里执行安装指令:
npm i stylus-loader stylus
webpack.config.js 代码更新如下:
const path = require("path");//nodejs里面的基本包,用来处理路径
const VueLoaderPlugin = require('vue-loader/lib/plugin');
//__dirname表示文件相对于工程的路径
module.exports ={
entry: path.join(__dirname, 'src/index.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
plugins: [
// make sure to include the plugin for the magic
new VueLoaderPlugin()
],
mode:'none',
module: {
rules: [
{//通过vue-loader来识别以vue结尾的文件,正则表达式中的点需要转义
test: /\.vue$/,
loader: 'vue-loader'
},
{//通过vue-loader来识别以vue结尾的文件
test: /\.css$/,
//css的处理方式不同,有嵌入在页面style标签里的,有从外部文件引入的,我们这里用use来声明
use: [
'style-loader',//接受潜在页面内部的style标签的文件。
'css-loader'
]
},
{
test: /\.styl$/,
use: [
'style-loader',
'css-loader',
'stylus-loader'
]
},
{//处理图片文件
test: /\.(gif|jpg|jpeg|png|svg)$/ ,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 20, //将所有小于1kb的图片都转为base64形式
name: '[name]-aaa.[ext]'
}
},
]
}
]
}
}
我们新建一个styls,我们想要在vscode中使用stylus需要安装一个插件:
安装完成之后,重新启动就可以了。我们新建的styl文件如下:
代码:
test-stylus-.styl
body
font-size 20px
这种写法是不是看上去落落大方,透露一股简约风范。我们再将这个styl文件在入口文件中引用进来。
入口文件 index.js
//这是工程的入口文件
import Vue from 'vue';
import App from './app.vue';
import './assets/styles/test.css';
import './assets/styles/test-stylus.styl';
import './assets/images/vue.png';
const root = document.createElement('div')
document.body.appendChild(root)
//mount就是讲我们的App挂载到root这样一个根节点中去
new Vue({
render: (h) => h(App)
}).$mount(root)
接着我们就可以编译一下,继续执行npm run build 指令编译
webpack配置webpack-dev-server
这个包是咱们在开发环境用的包处理工具,我们这里先install这个包。
npm i webpack-dev-server
这部分内容是在换了个网络环境下完成的,因为移动的网速度不快,这里使用了cnpm来安装。使用方式就是在package.json文件里添加:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack.config.js",
"dev": "webpack-dev-server --config webpack.config.js"
}
这里添加完dev指令后需要到webpack.config.js下修改一部分内容来专门适应我们的开发环境。
首先我们需要添加target属性,将其设置为‘web’,由于我们使用的是浏览器编译平台,所以这里设置为web,这也是webpack这个属性的默认设置,所以写不写无所谓。更多的target属性值我这里给他家提供腾讯云的解释:cloud.tencent.com/developer/s…
接下来我们需要区分全局的一个环境,很容易就想到需设置一个全局的环境变量来做区分控制,我们在build指令后面添加代码
我们如果不想区分不同系统,写一套代码来适应多个系统,我们这里就使用到了 cross-env,我们在指令前面添加cross-env
当然这个包也是需要安装的,执行
cnpm i cross-env
最后我们还需要给dev下的指令配置一个变量值,用来区分两套环境
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
"dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js"
}
这里完成之后我们就可以在webpack.config.js文件里面进行判断了。
我们现在文件下新建一个变量
const isDev = process.env.NODE_ENV === 'development';
我们启动时设置的脚本变量都是可以通过process.env这个对象来获取的。更多关于process.env的内容可以到webpack.docschina.org/guides/envi… 读阅
这里我们判断如果是dev环境的话,我们就给webpack.config.js添加一些配置。
if(isDev){
config.devServer = {
port: 8080,
host: '0.0.0.0',
overlay: {
erros: true,
}
}
}
首先我们给devServer属性添加一个port,因为我们新建的是一个服务,所以肯定要一个端口,接下来我们配置host,这里使用‘0.0.0.0’也是有好处的。这样可以通过127.0.0.1(本地默认地址)来进行访问,同时还可以在别人的机器上来访问,因为如果设置成‘localhost’的话通过ip是不能访问的。这里大家了解一下,更多相关derserver内容可以去这里参考:www.webpackjs.com/configurati… overlay属性是在我们编译的过程中能够让任何的错误都显示到网页上面。最后我们加完了这些基础的配置之后回过头来发现,我们好像配置的只是js、css、img文件,没有html页面去容纳它们。这个时候我们用到一个webpack的一个插件html-webpack-plugin,我们照样来安装一下它:
cnpm i html-webpack-plugin
并且在webpack.config.js文件的头部将它require进来,同时在plugin中新建。这里推荐一篇博客关于html-webpack-plugin的,大家可以参阅一下www.cnblogs.com/wonyun/p/60…。
到这里我们基本的配置就完成了,最后需要了解一下webpack.DefinePlugin,我们在代码中的plugin里添加:
plugins: [
// make sure to include the plugin for the magic
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: isDev ? '"development"' : '"production"'
}
}),
new VueLoaderPlugin(),
new HTMLPlugin()
],
这里我们用到了webpack,所以需要将 webpack 这个变量引用进来。
说到这里,理论上我们已经完成的本地开发环境的编译,通过npm run dev就可以进行编译,我们来试验一下。
执行:npm run dev
这里在浏览器里面输入localhost:8000会出现:
说明我们npm run dev
已经启动成功了。
这里我们再介绍一些devserver其他的一些配置。
文章出处引自于此,更详细的内容,希望大家参考: blog.csdn.net/u013368397/…
转载自:https://juejin.cn/post/6989506173447700511