webpack4+vue 的基本打包配置详解

前提:确保已安装node,为了安装速度快一些,使用cnpm源,安装cnpm:npm i cnpm -g 

注意:Mac环境下,操作全局环境,需要开启root权限,使用sudo npm i cnpm -g  (sudo表示开启root权限,其他操作全局的npm或者cnpm同理,需要在命令前面加上sudo)

1、安装webpack4

建立如下的目录结构,注意文件夹和文件名都和图中相同:

webpack4+vue 的基本打包配置详解_第1张图片

接下来全局安装webpack,进入项目根目录(webpack-study目录)的终端,输入命令:cnpm i webpack -g

输入命令webpack-v查看版本,发现会报如下提示:

因为webpack4开始,需要配套安装webpack-cli,输入no,因为webpack刚刚是全局安装的,所以webpack-cli也需要全局安装。

输入命令:cnpm i webpack-cli -g

安装完成后,再次输入webpack-v查看版本,如果出现下图所示版本号,则webpack4安装成功:

2、开始打包

输入命令 cnpm init 进行项目的初始化,成功之后,根目录下会多一个package.json文件。

安装jquery包: cnpm i jquery -D (-D 表示将安装的包保存在package.json文件中的devDependencies对象中)。

注意:一定加上-D,如果中途安装包出现错误的时候,把整个node_module包删掉,然后执行cnpm i命令,它会根据package.json文件中的配置去下载那些包。

接下来在index.html文件中输入以下代码:




    
    
    
    Document


    

在index.js文件中输入以下代码:

import $ from 'jquery'
$('#test').text('August')

浏览器中打开index.html文件,会发现控制台报错,因为import是ES6的语法,浏览器不能解析。

webpack4已经不能用webpack file1 file2来进行打包了,直接输入命令:webpack

webpack4会自动寻找src目录下的index.js文件,并将打包之后的文件,自动新建dist文件夹,并默认dist下的main.js文件就是打包生成的文件。

注意一定要有src目录下的index.js文件,否则会报错。

运行webpack命令之后,有这样的警告:

webpack4需要指定生产还是开发模式,再次输入命令:webpack --mode development 指定开发模式,可以发现警告已经没有了。

但是每次输入这个命令比较繁琐,可以在package.json文件中的scripts对象中新增一条配置:

webpack4+vue 的基本打包配置详解_第2张图片

现在执行命令 npm run dev 就相当于webpack --mode development,可以把这个命令执行试一下。

最后,我们将index.html引入的js文件改成刚刚生成的main.js文件之后,再用浏览器打开index.html,可以看到代码成功生效了。

所以webpack的作用之一,就是将一些高级语法转换成浏览器可以识别的语法,兼容浏览器。

3、webpack配置文件

在根目录下新建文件webpack.config.js文件,注意,一定是这个名字,webpack打包时会自动寻找这个配置文件。

如果不想有src目录,也不想有index.js文件,想随便自定义自己的文件,这个时候就可以修改webpack配置文件。

在这个配置文件中输入:

const path = require('path')
module.exports = {
    entry: path.join(__dirname, './src/main.js'),//入口文件
    output: {
        path: path.join(__dirname, './dist'), //出口(打包后)文件路径
        filename: 'bundle.js' //出口(打包后))文件名
    }
}

entry指定的是你想要打包的入口文件,output指定的是打包后的出口文件,现在将src目录下的index.js文件重命名为main.js文件,并将dist文件夹删除,最后运行打包命令:npm run dev。

注:每次修改配置文件都需要重新运行打包命令。

webpack4+vue 的基本打包配置详解_第3张图片

如上图所示,webpack配置文件生效,最终将main.js文件打包成了bundle.js文件。

需要注意的是,index.html文件之前引入的是打包后的main.js文件,现在打包后文件我们指定为bundle.js文件,所以需要将index.html引入的js文件改为bundle.js,打开页面,能正常显示。

4、webpack-dev-server

假设现在有个需求,需要将页面内容的August改为September,很简单,只需要将src下main.js修改一下就行,问题是,由于html引用的是打包后文件,所以需要改完需要再执行打包命令。这个时候,假设又需要改回August了,你需要再修改,再打包,每次修改一点想看页面效果,都需要重新打包,这样太繁琐。

所以webpack-dev-server就出现了,它可以实时监听我们文件的变化,自动帮我们编译打包命令。

安装webpack-dev-server:cnpm i webpack-dev-server -D

安装之后出现下图所示警告:

由于webpack-dev-server依赖webpack,但是我们webpack是安装在全局的,需要再这个项目下安装局部的webpack,执行以下命令:

cnpm i webpack -D

cnpm i webpack-cli -D

安装成功之后,打开package.json文件,scripts中dev属性修改成如下代码:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --mode development"
  },

webpack-dev-server已经集成了webpack命令的作用,所以运行webpack-dev-server命令和webpack一样,只不过webpack-dev-server还能自动监听文件变化,自动打包。

运行命令:npm run dev

webpack-dev-server会自动启动一个本地服务器(webpack是基于node的),默认端口是8080,在浏览器输入localhost:8080,可以看到如下页面,说明安装配置成功:

webpack4+vue 的基本打包配置详解_第4张图片

这需要我们手动打开浏览器输入地址,webpack-dev-server提供了几个参数,可以执行完命令后,自动打开浏览器,package.json文件作如下修改:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --mode development --open 'google chrome' --port 3000"
  },

如上配置意思是,默认以chrome浏览器打开,并修改默认端口为3000,保存文件后,重新运行npm run dev命令,可以发现浏览器已经自动打开了。

此外,还有几个参数:

--hot表示热加载,意思是默认每次重新编译都是生成一个新的打包文件,热加载则是你改了哪些,就局部更新打包文件的部分内容。

如果想局域网内其他主机也可以访问你的项目,需要增加配置,----host 0.0.0.0

如果想打开浏览器就能看到页面而不是这个目录结构,可以增加配置, --content-base src/

ps:除了可以在package.json文件中配置dev,还可以在webpack.config.js文件中通过devServer属性来修改配置。

然后我们修改main.js文件,改成September,然后刷新页面,发现并没有生效。

回头看下刚刚运行webpack-dev-server的命令后的提示信息:

第二行告诉我们它默认的output(生成的打包文件的输出目录)是/,也就是根目录,所以我们需要将index.html文件中的引入路径改为:


    

现在对main.js作任何修改都能不用执行打包命令,也不用刷新浏览器就能看到变化。

这里默认打包后的文件在根目录下,但是根目录下,我们并没有看到有这个文件,其实它是在内存中存放,既然打包后的文件在内存中存放,那是不是也可以让index.html文件也在内存中存放,并自动引入我们打包后的js文件呢?

这需要安装插件:html-webpack-plugin

5、html-webpack-plugin

安装:cnpm i html-webpack-plugin -D

安装之后,需要在webpack的配置文件webpack.config.js中作如下修改:

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    entry: path.join(__dirname, './src/main.js'),//入口文件
    output: {
        path: path.join(__dirname, './dist'), //出口(打包后)文件路径
        filename: 'bundle.js' //出口(打包后))文件名
    },
    plugins: [
        new HtmlWebpackPlugin({
            // 指定模板页面,将来根据这个指定的路径生成内存中的页面
            template: path.join(__dirname, './src/index.html'), 
            // 指定生成页面的名称
            filename: 'index.html'
        })
    ]
}

然后我们将index.html中引入的script文件删除,不引入任何的script文件,然后重新运行npm run dev,记得保存修改后的配置文件。

运行之后,可以看到页面会正常显示。

html-webpack-plugin会帮我们将html文件存到内存中,并自动帮我们引入打包后的文件,我们可以查看下网页源代码:

webpack4+vue 的基本打包配置详解_第5张图片

可以看到多了一个script引入文件。

6、css-loader,style-loader

接下来我们新增一个css文件,尝试改变下文字颜色,然后在main.js中引入这个css文件:

import $ from 'jquery'
import './main.css'
$('#test').text('August')

保存之后,自动打包会报错:

webpack4+vue 的基本打包配置详解_第6张图片

第三行提醒我们需要一个合适的loader,因为webpack处理不了非js文件,所以我们需要安装第三方加载器,loader的作用就是解析这类webpack不能解析的文件,css需要安装css-loader和style-loader。

cnpm i css-loader style-loader -D

安装完成之后,需要在webpack配置文件进行相应的配置,增加了module属性:

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    entry: path.join(__dirname, './src/main.js'),//入口文件
    output: {
        path: path.join(__dirname, './dist'), //出口(打包后)文件路径
        filename: 'bundle.js' //出口(打包后))文件名
    },
    plugins: [
        new HtmlWebpackPlugin({
            // 指定模板页面,将来根据这个指定的路径生成内存中的页面
            template: path.join(__dirname, './src/index.html'), 
            // 指定生成页面的名称
            filename: 'index.html'
        })
    ],
    module: {
        rules: [
            {test: /\.css$/, use: ['style-loader', 'css-loader']}
        ]
    }
}

这条rule的意思是,检测到.css结尾的文件时,使用后面的加载器。

注意:loader的加载顺序是从后往前的,先解析css,再将结果交给style,顺序不能交换,保存配置文件之后重新npm run dev,可以看到css代码已经生效。

同理,less和scss也是需要安装加载器。

less安装:cnpm i less less-loader -D (less-loader内部需要依赖less)

scss安装:cnpm i node-sass sass-loader -D (sass-loader内部需要依赖node-sass)

接着配置webpack配置文件,rules中在刚刚css那条规则后面再增加scss和sass的配置:

rules: [
            {test: /\.css$/, use: ['style-loader', 'css-loader']},
            {test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},
            {test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader']}
        ]

新增一个less和scss文件,随便写一点样式,然后在main.js中import这两个文件,最后执行npm run dev,如果刚刚写的样式生效,则安装配置成功。

7、url-loader

现在我们尝试在css文件中添加一条样式,{background: url(图片路径)}

会发现会报错,和我们第一次引入css-loader的错一样,提醒我们需要一个加载器来解析url。

安装:cnpm i url-loader -D

和之前一样,也是在配置文件中新增一条rule:

rules: [
            {test: /\.css$/, use: ['style-loader', 'css-loader']},
            {test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},
            {test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader']},
            {test: /\.(jpg|jpeg|gif|png|)$/, use: 'url-loader'},
            {test: /\.(ttf|woff2|woff|eot|svg)$/, use: 'url-loader'}, // 处理字体文件
        ]

第二行的url-loader是为了处理fontawesome或者类似的图标库,本文不再说图标引入,可以自行参考fontawesome官网,通过cnpm安装,然后import css文件,配置不需要做其他修改。

更改配置之后,执行npm run dev可以看到图片出现在页面上。

8、babel-loader

babel是JavaScript的编译器,webpack只能解析一部分es6的语法,如果我们用了更高级的es6的语法,例如我们可以在main.js中添加以下代码:

class Person {
    static info = {name: 'kun', age: 20}
}
console.log(Person.info)

这段代码是什么意思,我们先不用管,只需要知道这是ES6的语法,会发现又报错:需要一个loader。

这里以最新版今年8月份发布的babel 8 版本为例安装(由官方文档可知之前的stage已移除):

cnpm i babel-loader @babel/core -D

cnpm i @babel/plugin-transform-runtime @babel/runtime @babel/plugin-proposal-class-properties  -D

cnpm i @babel/preset-env

安装完成之后,项目根目录(即webpack.config.js同一级目录)下新建一个babel配置文件:.babelrc(这是个json格式的配置文件)

{
    "plugins": [
        "@babel/plugin-transform-runtime",
        "@babel/plugin-proposal-class-properties"
    ],
    "presets": [
        [
          "@babel/preset-env",
          {
            "useBuiltIns": "entry"
          }
        ]
      ]
}

最后,像之前一样在webpack配置文件中新增一条rule

{test: /\.js$/, use: 'babel-loader', exclude: /node_modules/}

exclude的意思是,除了node_modules下的js文件,其他js都使用babel-loader解析,原因是,node_modules下js文件太多,都打包耗费性能,并且没必要打包,打包之后最终生成的代码会出错。

9、vue的安装配置

cnpm i vue -D

cnpm i vue-loader vue-template-compiler -D (和之前css文件一样,vue-loader是为了解析.vue文件,此处不再演示,未安装时,报错:需要一个合适的loader,)

webpack配置文件新增一条rule:

{test: /\.vue$/, use: 'vue-loader'}

这里需要注意的是,15.x之后版本的vue-loader还需要配置插件:

const VueLoaderPlugin = require('vue-loader/lib/plugin')

再在plugins属性中增加一条:

new VueLoaderPlugin()

index.html修改文件内容如下:




    
    
    
    Document


    

main.js修改文件内容如下:

import $ from 'jquery'
import './main.css'
import './main.less'
import './main.scss'
import Vue from 'vue'

var vm = new Vue({
    el: '#app',
    components: {
        test: {template: '

August

'} } })

如果我们是通过script方式引入vue.js的话,此时页面上应该有h1,但是我们运行npm run dev之后,发现报错:

You are using the runtime-only build of Vue where the template compiler is not available.

在node_modules文件夹下,找到刚刚安装的vue文件夹,里面有个package.json文件,打开这个文件,找到main属性:

"main": "dist/vue.runtime.common.js"

import的文件默认是package.json文件中main属性指定的文件,可以发现它并不是我们熟悉的vue.js文件,import的是运行时版本,不是完整版,参考vue官方文档:

  • 完整版:同时包含编译器和运行时的版本。

  • 编译器:用来将模板字符串编译成为 JavaScript 渲染函数的代码。

  • 运行时:用来创建 Vue 实例、渲染并处理虚拟 DOM 等的代码。基本上就是除去编译器的其它一切。

也就是说,template渲染的字符串,运行时vue都无法解析。

解决方法有两类,一是使用完整版vue,二是使用运行时vue,但是需要找其他解决方法。先看第一类:

1、可以明确指定import的文件:

import Vue from 'vue/dist/vue.js'

2、第二种依旧是import vue from ‘vue’

但是需要在webpack配置文件中增加一个属性:

resolve: {
        alias: {
            'vue$': 'vue/dist/vue.js'
        }
    }

这两种都可以解决问题,页面正常显示,但是完整版比运行时vue大,性能不如运行时vue,官方也更推荐运行时vue,因为vue-loader可以编译vue文件,所以事实上是不需要vue的编译功能的。

新增一个test.vue文件:


将main.js作如下修改:

import $ from 'jquery'
import './main.css'
import './main.less'
import './main.scss'
import Vue from 'vue'
import test from './test.vue'

var vm = new Vue({
    el: '#app',
    render: function(h) {
        return h(test)
    }
})

注意需要import test组件。

render函数也可以渲染组件,且template编译也是调用了render函数,运行时vue只能通过render函数来渲染组件,components不行,但是.vue文件可以使用components(因为使用了vue-loader进行解析),新增一个文件test2.vue:


将test组件作如下修改:


至此,webpack+vue所需要配置的主要插件、加载器大概就是这些了。

你可能感兴趣的:(webpack,web)