15 小程序-VUE-webpack各类配置操作使用

1.webpack

1.1认识webpack

       At its core, webpack is a static module bundler for modern JavaScript applications. 从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具,p两个点来解释上面这句话:模块 和 打包

       可以理解为:我们开发项目中很多文件,js,hbs,sass,png。如果贸然直接给服务器部署,那么浏览器可能不支持,比方说sass浏览器不支持,需要一些工具打包识别转换,则遇到打包工具很多种,比如webpack,grunt,rollup(vue源码基于rollup构建)

image

   webpack模块化概念:      

         没有webpack,则浏览器仅能支持es6模块化语法,那么在webpack里面就可以使用amd,cmd,commonjs进行模块化开发,后期进行转化,而不是简单转化为es6(可能部分浏览器不支持es6).而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用(在后续我们会看到)。

      打包概念

  • 理解了webpack可以帮助我们进行模块化,并且处理模块间的各种复杂关系后,打包的概念就非常好理解了。
  • 就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。
  • 并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。
  • 但是打包的操作似乎grunt/gulp也可以帮助我们完成,它们有什么不同呢?

     和ngrunt/gulp区别-grunt/gulp的核心是Task

  • 我们可以配置一系列的task,并且定义task要处理的事务(例如ES6、ts转化,图片压缩,scss转成css)
  • 之后让grunt/gulp来依次执行这些task,而且让整个流程自动化。
  • 所以grunt/gulp也被称为前端自动化任务管理工具

image

什么时候用grunt/gulp呢?

  • 如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念。
  • 只需要进行简单的合并、压缩,就使用grunt/gulp即可。
  • 但是如果整个项目使用了模块化管理,而且相互依赖非常强,我们就可以使用更加强大的webpack了。

所以,grunt/gulp和webpack有什么不同呢?

  1. grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。
  2. webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是他附带的功能。


1.2 webpack的安装

    webpack依赖node环境,而node为了帮助我们管理更多的代码,自带工具npm帮忙我们进行依赖包管理。npm-node packages manager

     全局安装webpack(这里我先指定版本号3.6.0,因为vue cli2依赖该版本,2里面webpack配置比较清晰)

  • 局部安装webpack(后续才需要)-save-dev`是开发时依赖,项目打包后不需要继续使用的。

为什么全局安装后,还需要局部安装呢?

  • 在终端不管是cmd还是idea直接执行webpack命令,使用的全局安装的webpack
  • 当在idea里面terminal中遇到package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack

1.3 webpack的起步

我们创建如下文件和文件夹:文件和文件夹解析:

image

  • dist文件夹:用于存放之后打包的文件 disturbtion(发布)
  • src文件夹:用于存放我们写的源文件

         main.js:源文件,是项目的入口文件。具体内容查看下面详情。

        mathUtils.js:定义了一些数学工具函数,可以在其他地方引用,并且使用。具体内容查看下面的详情。

  • index.html:浏览器打开展示的首页html
  • package.json:通过npm init生成的,npm包管理的文件(暂时没有用上,后面才会用上)

mathUtils.js文件中的代码:

image

main.js文件中的代码:

image

          webpack ./src/main.js ./dist/bundle.js 就是将src的main.js打包至dist/bundle.js。然后在index.html中引用bundle.js即可使用


1.4 webpack的配置

       传统    webpack ./src/main.js ./dist/bundle.js 需要手动给予入口文件js和目标文件js。我们可以进行单独配置,这样终端输入webpack即可自动识别。package.json是一个项目,单独做个依赖环境配置时候使用。

      这个需要npm install,产生package.json,里面包含一些项目文件配置信息,然后在webpack.config.js中输入 const path=requrie('path')。后面path会在环境变量中查找,然后全局搜索配置的 path:path.resolve(__dirname,'dist'), 进行__dirname,'dist'两个进行拼接成为绝对路径。此处__dirname是自带关键字。不用定义。如此 webpack自识别,当然做映射后,和npm run build/serve是一个用途。都可以启动项目。我们映射在package.json中进行配置

image

        这样配置的好处是运行build时,优先找的是本地webpack。找不到再去全局的。

  •         开发时依赖package.json中 devDependencies。不用写,npm install按照时候自动添加
  •         运行时依赖dependencies。

const path=require('path')
module.exports={
    entry:'./src/main.js',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'bundle.js'
    },
}

但是,每次执行都敲这么一长串有没有觉得不方便呢?OK,我们可以在package.json的scripts中定义自己的执行脚本。

  • package.json中的scripts的脚本在执行时,会按照一定的顺序寻找命令对应的位置。
  • 首先,会寻找本地的node_modules/.bin路径中对应的命令。
  • 如果没有找到,会去全局的环境变量中寻找。
  • 如何执行我们的build指令呢?

1.5 loader的使用-是webpack的扩展

      loader就是使得css样式配置文件也像main.js mathUtils.js文件一样,都做模块化处理。loader是webpack中一个非常核心的概念。在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等等。

       webpack本身的能力来说,对于这些转化是不支持的。那怎么办呢?给webpack扩展对应的loader就可以啦

  • 步骤一:通过npm安装需要使用的loader
  • 步骤二:在webpack.config.js中的modules关键字下进行配置

        webpack也不可能找到它,因为我们只有一个入口main.js,webpack会从入口开始查找其他依赖的文件。在入口文件中引用:

我们一般多种文件的loader都去webpack.js.org中查找。 其中--save-dev表示开发时依赖。

      使用css样式打包,需要用css-loader和style-loader

npm install --save-dev css-loader

image


css-loader只负责css文件加载,不负责生效。还需要用style-loader将样式添加到dom中,webpack读取loader时,从右往左读取

const path=require('path')
module.exports={
entry:'./src/main.js',
output:{
path:path.resolve(__dirname,'dist'),
filename:'bundle.js'
},

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

}

npm install style-loader --save-dev

image

(node:11068) UnhandledPromiseRejectionWarning: TypeError: this.getResolve is not a function

跟着学习视频看,老师使用的webpack版本是3.6.0,所以对应css-loader的版本是2.0.2,所以卸载重新装一下就好了
npm uninstall css-loader(卸载)
npm install css-loader@2.0.2 --save-dev

image

      使用less样式打包,需要用css-loader和style-loader

npm install --save-dev less-loader less

module.exports = {
    ...
    module: {
        rules: [{
            test: /\.less$/,
            use: [{
                loader: "style-loader" // creates style nodes from JS strings
            }, {
                loader: "css-loader" // translates CSS into CommonJS
            }, {
                loader: "less-loader" // compiles Less to CSS
            }]
        }]
    }
};

image

      使用  url-loader 样式打包,需要用 npm install --save-dev url-loader

npm install --save-dev url-loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }] ] } }

image

        如果你仔细阅读webpack打包的js文件,发现写的ES6语法并没有转成ES5,那么就意味着可能一些对ES6还不支持的浏览器没有办法很好的运行我们的代码。在前面我们说过,如果希望将ES6的语法转成ES5,那么就需要使用babel。而在webpack中,我们直接使用babel对应的loader就可以:

npm install --save-dev babel-loader@7 babel-core babel-preset-es2015

     配置webpack.config.js文件,之后npm run build

image



1.6 webpack中配置Vue

      后续项目中,我们会使用Vuejs进行开发,而且会以特殊的文件来组织vue的组件。所以,下面我们来学习一下如何在我们的webpack环境中集成Vuejs,现在,我们希望在项目中使用Vuejs,那么必然需要对其有依赖,所以需要先进行安装注:因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖(因此尾部不用加-dev),而且早期引用vue.js不是模块化开发,此处用webpack则是用vue依赖进行模块化开发。相当于去node_modules 找vue,使用的其实是node——modules导出的export 出vue,我们使用它

image

那么,接下来就可以按照我们之前学习的方式来使用Vue了

image

初次使用报错如下:

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.

这个错误的问题来源是vue构建发布版本时候,有两种版本

  • runtime-only  代码中,不可以有任何的template,因为编译不了组件
  • runtime-compiler  代码中,可以有template,因为compiler可以编译组件

我们指定时,参考下面的,则构建不会用默认的,见下下图片

image

这个错误说的是我们使用的是runtime-only版本的Vue,什么意思,所以我们修改webpack的配置,添加如下内容即可

image

image

     其实在SPA(单页面复用 sinple page webapplication)开发模式中,经过vue-rooter,因此index.html很少进行修改,在正常运行之后,我们来考虑另外一个问题:

  • 如果我们希望将data中的数据显示在界面中,就必须是修改index.html
  • 如果我们后面自定义了组件,也必须修改index.html来使用组件
  • 但是html模板在之后的开发中,我并不希望手动的来频繁修改,是否可以做到呢?

解决方案:定义template属性:

  • 在前面的Vue实例中,我们定义了el属性,用于和index.html中的#app进行绑定,让Vue实例之后可以管理它其中的内容
  • 这里,我们可以将div元素中的{{message}}内容删掉,只保留一个基本的id为div的元素
  • 但是如果我依然希望在其中显示{{message}}的内容,应该怎么处理呢?
  • 我们可以再定义一个template属性,代码如下:

image

      一句话,vue对象中同时有el和template后,则template在解析时,会将el指向的实例进行替换。

     终极解决方案-不改html代码,而实现实例替换-抽离出组件化开发

//抽离组件
const cpn={
    template:`
         <div>
            <h2>{{message}}</h2>
            <button @click="btnclick">按钮</button>
         </div>
    `,
    data(){
        return{
            message:'hello webpack'
        }
    },
    methods:{
        btnclick(){
            console.log('我爱大中华');
        }
    }
}


const app=new Vue({
    el:'#app',
    //使用组件
    template:`<cpn></cpn>`,
    data:{
    },
    components:{
        //注册组件
        cpn
    }
})

重新打包,运行程序,显示一样的结果和HTML代码结构

那么,el和template模板的关系是什么呢?

  • 在我们之前的学习中,我们知道el用于指定Vue要管理的DOM,可以帮助解析其中的指令、事件监听等等。
  • 而如果Vue实例中同时指定了template,那么template模板的内容会替换掉挂载的对应el的模板。

这样做有什么好处呢?

  • 这样做之后我们就不需要在以后的开发中再次操作index.html,只需要在template中写入对应的标签即可
  • 但是,书写template模块非常麻烦怎么办呢?
  • 没有关系,稍后我们会将template模板中的内容进行抽离。
  • 会分成三部分书写:template、script、style,结构变得非常清晰。

代码修复如下:

image

       ERROR in ./src/main.js
Module not found: Error: Can't resolve 'vue/App.vue' in 'D:\Code\vue\hellworld\05-webpack\src'
  @ ./src/main.js 7:11-33

image


但是一个组件以一个js对象的形式进行组织和使用的时候是非常不方便的

  • 一方面编写template模块非常的麻烦
  • 另外一方面如果有样式的话,我们写在哪里比较合适呢?
  • 现在,我们以一种全新的方式来组织一个vue的组件

但是,这个时候这个文件可以被正确的加载吗?

  • 必然不可以,这种特殊的文件以及特殊的格式,必须有人帮助我们处理。
  • 谁来处理呢?vue-loader以及vue-template-compiler。
  • 安装vue-loader和vue-template-compiler

npm install vue-loader vue-template-compiler --save-dev

修改webpack.config.js的配置文件:

image

1.7 plugin的使用

         plugin是什么?plugin是插件的意思,通常是用于对某个现有的架构进行扩展。webpack中的插件,就是对webpack现有功能的各种扩展,比如打包优化,文件压缩等等。

      loader和plugin区别

  • loader主要用于转换某些类型的模块,它是一个转换器、加载器。
  • plugin是插件,它是对webpack本身的扩展,是一个扩展器。

     plugin的使用过程:

  • 步骤一:通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)
  • 步骤二:在webpack.config.js中的plugins中配置插件。

添加版权的Plugin

         我们先来使用一个最简单的插件,为打包的文件添加版权声明,该插件名字叫BannerPlugin,属于webpack自带的插件。按照下面的方式来修改webpack.config.js的文件:

image

重新打包程序:查看bundle.js文件的头部,看到如下信息

image

如果webpack是4.0以后的,则需要匹配vue-loader 14.0之后的版本

https://img2020.cnblogs.com/blog/1582675/202004/1582675-20200418220200637-1119910518.png

       打包html的plugin

目前,我们的index.html文件是存放在项目的根目录下的。

  • 我们知道,在真实发布项目时,发布的是dist文件夹中的内容,但是dist文件夹中如果没有index.html文件,那么打包的js等文件也就没有意义了。
  • 所以,我们需要将index.html文件打包到dist文件夹中,这个时候就可以使用HtmlWebpackPlugin插件

HtmlWebpackPlugin插件可以为我们做这些事情:

  • 自动生成一个index.html文件(可以指定模板来生成)
  • 将打包的js文件,自动通过script标签插入到body中

       安装HtmlWebpackPlugin插件

npm install html-webpack-plugin --save-dev

使用插件,修改webpack.config.js文件中plugins部分的内容如下:

  • 这里的template表示根据什么模板来生成index.html
  • 另外,我们需要删除之前在output中添加的publicPath属性
  • 否则插入的script标签中的src可能会有问题

image


const HtmlWebpackPlugin=require('html-webpack-plugin')

       js压缩的Plugin

       在项目发布之前,我们必然需要对js等文件进行压缩处理,这里,我们就对打包的js文件进行压缩.我们使用一个第三方的插件uglifyjs-webpack-plugin,并且版本号指定1.1.1,和CLI2保持一致

npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

       修改webpack.config.js文件,使用插件:

主要做法1是将空格换行去除,2是将变量命名简化调整。

image

查看打包后的bunlde.js文件,是已经被压缩过了。

image

       搭建本地服务器

        webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。不过它是一个单独的模块,在webpack中使用之前需要先安装它。

npm install --save-dev webpack-dev-server@2.9.1

devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:

  • contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist
  • port:端口号,也就是跟在localhost后面端口号,默认8080
  • inline:页面实时刷新
  • historyApiFallback:在SPA页面中,依赖HTML5的history模式

webpack.config.js文件配置修改如下

image

在这里需要注意,我们终端执行webpack-dev-server可能失败,因为默认终端在全局找,当然我们可以再配置另外一个scripts:open参数表示直接打开浏览器

image

image

package.json的代码
{
"name": "meetwebpack",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"dev": "webpack-dev-server --open"
},
"author": "",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-es2015": "^6.24.1",
"css-loader": "^2.0.2",
"file-loader": "^4.3.0",
"html-webpack-plugin": "^3.2.0",
"less": "^3.12.2",
"less-loader": "^5.0.0",
"style-loader": "^2.0.0",
"stylus": "^0.54.8",
"stylus-loader": "^4.3.0",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^1.1.2",
"vue-loader": "^14.2.2",
"vue-template-compiler": "^2.6.12",
"webpack": "^3.6.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^2.9.1"
},
"dependencies": {
"vue": "^2.6.12"
}
}

webpack-dev-server的配置抽离

开发时需要的配置,例如下面,在实际部署不需要,应该可以抽离出来

devServer:{
contentBase:'./dist',
inline:true
}
编译需要的东西  也进行抽离  new UglifyjsWebpackPlugin()

我们可以考虑在同一文件夹级别,建个build文件夹,内含 base.config.js(公共配置 )、dev.config.js(开发配置)、prod.config.js(生产配置)

image









posted @ 2020-11-25 09:52  芒果侠  阅读(553)  评论(0编辑  收藏  举报