webpack、Vue

目录

一、起步

    1、安装    2、基本使用    3、创建bundle文件    4、使用配置文件

二、开发

    1、webpack-dev-server自动打包编译    2、html-webpack-plugin自动添加js入口文件

三、管理资源

    1、加载CSS、less、scss    2、加载图片    3、加载字体

四、bable处理高级js语法

五、Vue

    1、开发环境    2、完整版     3、运行时    4、vue-router    5、vue-resource    6、vuex

网页中常见的静态资源:JS(.js  .jsx  .coffee  .ts)、CSS(.css  .less  .sass  .scss)、Images(.jpg  .png  .gif  .bmp  .svg)、字体文件Fonts(.svg  .ttf  .eot  .woff  .woff2)、模板文件(.ejs  .jade  .vue)。静态资源使网页加载速度慢,因为要发起很多二次请求;静态资源间存在综复杂的依赖关系。解决办法:合并压缩(sprite、图片的Base64编码等)、解决各个包之间复杂的依赖关系。

webpack是基于Node.js开发的前端项目构建工具。本质上,webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有模块打包成一个或多个bundle。官网:https://webpack.github.io/  https://www.webpackjs.com/

Gulp是基于task任务的,webpack是基于整个项目进行构建的。

一、起步

1、安装

确保已安装Node.js最新的长期支持版本(LTS),因为使用旧版本可能遇到各种问题,可能缺少webpack功能以及/或者缺少相关package包。

包安装出错时,可删除node_modules文件夹,运行npm install重新安装所有包。也可以npm uninstall <包名>卸载相应的包。

(1)全局安装

运行npm i webpack -g全局安装。

(2)本地安装

对于大多数项目,建议本地安装(先全局安装,才能使用webpack命令)。使引入破坏式变更(breaking change)的依赖时,更容易分别升级项目。在项目根目录中运行以下命令安装到项目依赖中。

安装到最新版本:npm install --save-dev webpack
安装到特定版本:npm install --save-dev webpack@<version>

使用webpack 4+版本时,还需要安装CLI:npm install --save-dev webpack-cli,提供命令行(如webpack命令)和打包功能。

2、基本使用

webpack-demo         // 根目录
  |- package.json
  |- webpack.config.js // 配置文件
  |- /dist             // 发布的文件
    |- index.html        // 首页
    |- bundle.js
  |- /src              // 源代码
    |- /css
    |- /js
    |- /images
    |- main.js           // js入口文件
  |- /node_modules

创建项目基本的目录结构;运行npm init -y在根目录下创建package.json(项目是中文名使用npm init),使用npm管理项目中的依赖包;运行npm install webpack webpack-cli --save-dev本地安装webpack。

使用npm i jquery -S安装jquery类库。import $ from 'jquery'导入jquery类库。

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>起步</title>
</head>
<body>
    <ul>
      <li>这是第1个li</li>
      <li>这是第2个li</li>
      <li>这是第3个li</li>
      <li>这是第4个li</li>
    </ul>
    <script src="./bundle.js"></script>
</body>
</html>
/* main.js */
import $ from 'jquery' // 相当于node中,const $=require('jquery')

$(function(){
  // 设置背景色隔行变色
  $('li:odd').css('backgroundColor','pink');
  $('li:even').css('backgroundColor','#ddd');
})

import或require导入包的查找规则:项目根目录中node_modules文件夹->根据包名找对应的文件夹->package.json包配置文件->main属性,指定了该包在被加载时的入口文件。

3、创建bundle文件

“源”代码(/src)是用于书写和编辑的代码,“分发”代码(/dist)是构建过程产生的代码最小化和优化后的“输出”目录,最终将在浏览器中加载。

webpack能够很好地支持import和export语句、及多种其它模块语法。webpack会将代码“转译”,以便旧版本浏览器可以执行。

将src/main.js“转译”为dist/bundle.js:webpack .\src\main.js --output .\dist\bundle.js(入口文件路径 输出文件路径);或npx webpack,将脚本作为入口起点,然后输出为main.js。

4、使用配置文件

在webpack 4中,可以无须任何配置使用,然而大多数项目会需要很复杂的设置,webpack仍然要支持配置文件,这比在终端中手动输入大量命令要高效的多,所以让我们创建一个取代以上使用CLI选项方式的配置文件。

使用配置文件创建bundle:webpacknpx webpack --config webpack.config.js。在控制台直接输入webpack命令执行时,去项目根目录查找配置文件,解析得到导出的配置对象,拿到配置对象中指定的入口和出口,进行打包构建。webpack 4有约定,为了尽量减少配置文件的体积,默认约定了打包的入口是./src/index.js和打包的出口是./dist/main.js。

/* webpack.config.js */
const path=require('path')

module.exports={ // node语法
  entry:'./src/main.js', // 项目入口文件,默认为'./src/index.js'
  output:{
    filename:'bundle.js', // 输出的路径
    path:path.resolve(__dirname,'dist') // 输出的文件名
  }
}

导入包是,省略.jsx等后缀名;配置和使用@路径符号。

// webpack.config.js
module.exports={
  resolve:{
    extensions:['.js','.jsx','.json'], // 这几个文件后缀名可省略不写
    alias:{ // 别名
      '@':path.join(__dirname,'./src')
    }
  }
}

// index.js
import Welcome from '@/components/Welcome' // 省略了.jsx

二、开发

1、webpack-dev-server自动打包编译

使用webpack-dev-server工具实现代码自动打包编译,修改和保存任意源文件,web服务器就会自动重新加载编译后的代码。

(1)运行npm install --save-dev webpack-dev-server将该工具安装到项目的本地开发依赖。该工具依赖于webpack,在本地项目中必须安装webpack。

(2)在命令行直接运行webpack-dev-server命令进行打包,报错,因为webpack-dev-server是本地安装的,无法把它当作脚本命令。需要借助于package.json文件中的指令运行webpack-dev-server命令。在scripts节点下新增"dev": "webpack-dev-server"指令,运行npm run dev。或者新增"start": "webpack-dev-server --open --port 3000 --concentBase dist --hot",运行npm start打开服务器。

(3)命令参数

方式一:修改package.json的script节点

--open 自动在浏览器中打开该端口地址,后面可跟浏览器名称,如firefox
--port 修改运行时的端口号
--host 修改运行时的域名,如127.0.0.1
--contentBase 设置托管的根目录,在浏览器中直接打开该路径下的.html文件
--hot 启动浏览器热更新,不会重新生成bundle.js,只会生成一个.js和.json补丁保存局部更新的代码,并实现浏览器的无重载异步刷新(对css等有效果,对js无效果)

方式二:修改webpack.config.js文件,新增devServer节点

/* webpack.config.js */
const path=require('path')
const webpack=require('webpack') // 启用热更新使用

module.exports={
  devServer:{
    open:true,
    port:3000,
    contentBase:'./dist',
    hot:true
  },
  plugins:[
    new webpack.HotModuleReplacementPlugin() // 放置热更新的模块对象
  ]
}

(4)webpack-dev-server打包生成的bundle.js文件,在项目根目录<script src="/bundle.js"></script>。并没有存放到实际的物理磁盘上,而是直接托管到电脑的内存中,在根目录找不到。由于需要实时打包编译,放在内存中速度会非常快。

2、html-webpack-plugin自动添加js入口文件

html-webpack-plugin,自动根据指定页面在内存中生成一个新页面之后,所有的打包好的bundle会自动添加到新页面的body底部。不再需要指定启动目录和手动处理bundle.js的引用路径。

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

/* webpack.config.js */
const path=require('path')
const htmlWebpackPlugin=require('html-webpack-plugin')

module.exports={
  plugins:[ // 配置插件的节点
    new htmlWebpackPlugin({
      template:path.join(__dirname,'./dist/index.html'), // 指定模板页面
      filename:'index.html', // 指定生成页面名称,浏览器默认打开index.html
      title:'Output Management'
    })
  ]
}

三、管理资源

webpack默认只能打包处理JS类型的文件,如需引入任何其它类型的文件,需通过loader 。

webpack处理第三方文件类型的过程:发现要处理的文件不是JS文件,去配置文件中查找有没有对应的第三方loader规则;如果有,调用对应的loader处理这种文件类型,从后往前调用;处理完毕,把处理的结果交给webpack进行打包合并,输出到bundle.js。

1、加载CSS、less、scss

为了从JS模块中import一个CSS文件,需要在module配置中安装并添加style-loader和css-loader。

/* main.js */
import './css/index.css'
import './css/index.less'
import './css/index.scss'

npm install --save-dev style-loader css-loader

npm install --save-dev less less-loader less是less-loader内部依赖,不需要显式定义

npm install --save-dev node-sass sass-loader node-sass是sass-loader内部依赖,不需要显式定义

/* webpack.config.js */
module.exports={
  module:{ // 配置所有第三方模块的加载器
    rules:[ // 所有第三方模块的匹配规则
      {test:/\.css$/,use:['style-loader','css-loader']}, // 加载.css文件,从后往前调用
      {test:/\.less$/,use:['style-loader','css-loader','less-loader']}, // 加载.less文件
      {test:/\.scss$/,use:['style-loader','css-loader','sass-loader']}, // 加载.scss文件
    ]
  }
}

2、加载图片

file-loader和url-loader可以接收并加载任何文件。

npm install --save-dev file-loader 使用file-loader,图片不会被编码为base64

npm install --save-dev url-loader file-loader是url-loader内部依赖,不需要显式定义

{test:/\.(png|svg|jpg|gif)$/,use:'file-loader'}, // 处理图片
{test:/\.(jpg|png|gif|bmp|jpeg)$/,use:'url-loader?limit=7631&name=[hash:8]-[name].[ext]'}

limit给定的值是图片的大小(byte),如果图片大于等于给定的limit值,则不会被转为base64格式的字符串。

图片名默认会被修改为哈希值,防止重名冲突。name=[name].[ext]使图片保持原名,在前面加哈希值解决重名冲突。

3、加载字体

npm install --save-dev file-loader url-loader

{test:/\.(ttf|eot|svg|woff|woff2)$/,use:'url-loader'} // 处理字体文件

四、bable处理高级js语法

webpack默认只能处理部分ES6语法,一些更高级的ES6或ES7语法,需要借助第三方的loader处理,转为低级的语法后,把结果交给webpack打包到bundle.js中。

webpack 4.x | babel-loader 8.x | babel 7.x
npm install -D babel-loader @babel/core @babel/preset-env webpack

npm install -D @babel/runtime @babel/plugin-transform-runtime @babel-runtime是依赖

babel-preset-env是较新的ES语法。(使用了static关键字报错,可能是因为这只是提案,目前不支持)

babel对一些公共方法使用了非常小的辅助代码,如_extend。默认情况下会被添加到每一个需要它的文件中,引入babel runtime作为一个独立模块,来避免重复引入。禁用babel自动对每个文件的runtime注入,而是引入babel-plugin-transform-runtime使所有辅助代码从这里引用。

配置babel的loader规则时,必须把node_modules目录排除。否则,babel会把node_modules中所有的第三方JS文件都打包编译,打包速度非常慢且非常消耗CPU,且即使编译完毕项目也无法正常运行。

/* webpack.config.js */
module.exports={
  module:{
    rules:[
      {test:/\.js$/,use:'babel-loader',exclude:/node_modules/} // 配置babel处理ES6等高级语法
    ]
  }
}

在项目的根目录中,新建一个.babelrc的babel配置文件,该文件是JSON格式,不能写注释,字符串必须用双引号。preset预设,可翻译为语法。

{
  "presets":["@babel/preset-env"],
  "plugins":["@babel/plugin-transform-runtime"]
}

babel默认启用严格模式,如果要移除严格模式,npm install babel-plugin-transform-remove-strict-mode,并修改.babelrc。

{
  "plugins":["transform-remove-strict-mode"]
}

五、Vue

1、开发环境

开发环境下,Vue会提供很多警告来对付常见的错误与陷阱。当使用webpack构建工具时,Vue源码会根据process.env.NODE_ENV决定是否启用开发环境模式。

/* webpack.config.js */
// webpack 4+
module.exports={
  mode:'development'
}
// webpack 3及其更低版本
var webpack=require('webpack')

module.exports={
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV':JSON.stringify('production')
    })
  ]
}

2、完整版

npm install --save-dev vue

使用import Vue from 'vue'导入Vue构造函数时,"main": "dist/vue.runtime.common.js",只提供了runtime-only的方式。如果需要在客户端编译模板(如传入一个字符串给template选项,或挂载到一个元素上并以其DOM内部的HTML作为模板),就需要加上编译器,即完整版。否则会报错[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:

/* main.js */
import Vue from '../node_modules/vue/dist/vue.js'

方式2:每次需要重新启动服务器

/* main.js */
import Vue from 'vue'
/* webpack.config.js */
module.exports={
  resolve:{
    alias:{
      "vue$":"vue/dist/vue.esm.js" // 设置Vue被导入包时的路径
    }
  }
}

3、运行时

运行时版本相比完整版体积要小大约30%,所以应该尽可能使用这个版本。

npm install --save-dev vue

npm install --save-dev vue-loader vue-template-compiler vue-template-compiler是依赖

/* main.js */
import Vue from 'vue'
import login from './login.vue' // 导入login组件
new Vue({
  el:'#app',
  render:function(createElement){
    return createElement(login)
  }
  // 简写为render:c=>c(login)
})
/* webpack.config.js */
const VueLoaderPlugin=require('vue-loader/lib/plugin')
module.exports={
  module:{
    rules:[
      {test:/\.vue$/,use:'vue-loader'} // 配置.vue文件
    ]
  },
  plugins:[
    new VueLoaderPlugin()
  ]
}

4、vue-router

npm install --save-dev vue

npm install --save-dev vue-router

如果在一个模块化工程中使用它,必须通过Vue.use()明确地安装路由功能。

/* main.js */
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

import app from './app.vue'
import router from './router.js'

new Vue({
  el:'#app',
  render:c=>c(app),
  router
})

将<router-link>和<router-view>放到render渲染的<template>中。

/* app.vue */
<template>
  <div>
    <p>render渲染的组件</p>
    <router-link to="/foo">To Foo</router-link>
    <router-link to="/bar">To Foo</router-link>

    <router-view></router-view>
  </div>
</template>

将定义、注册路由抽离为router.js

​/* router.js */
import VueRouter from 'vue-router'

import foo from './main/Foo.vue'
import bar from './main/Bar.vue'

var router=new VueRouter({
  routes:[
    {path:'/foo',component:foo},
    {path:'/bar',component:bar}
  ]
})

export default router // 向外暴露router对象

5、vue-resource

npm install --save-dev vue

npm install --save-dev vue-resource

/* main.js */
import Vue from 'vue'
import VueResource from 'vue-resource'

Vue.use(VueResource)

6、vuex

npm install --save-dev vue

npm install vuex --save

npm install es6-promise --save Vuex依赖Promise,如果浏览器并没有实现Promise(如IE)

/* main.js */
import Vue from 'vue'
// import 'es6-promise/auto'
import Vuex from 'vuex'

Vue.use(Vuex)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章