模块化思想

// 1最早期就只是html和css处理网页

// 2发明一种语言来操作html和css js

// 3早期只是在html文件里直接在script标签里写一些脚本代码

// 4随着Ajax的出现,慢慢形成了前后端的分离

// 5客户端需要完成的事情越来愈多,代码量与日俱增

// 6为了应对代码量的增加,通常会将代码组织在多个js文件中,进行维护,就会出现许多问题

首先,当我们编写代码时,不通过模块化的思想想要引入一个js,通常是在html文件中创建一个script标签,引入我们需要的js,如果我们引入的是自己手写的js,在过个js文件中,或者多人合作开发时候,很容易发生变量重名的冲突。

// 变量命名冲突
// a.js 小明开发的
var a = true; // b.js 小红开发的
var a = false // index.html 中同时引入a.js、b.js后,小明记得自己的a变量是true //c.js //小明继续开发
if(a){
console.log('我定义的a变量是true')
}
这样就报错了,小明不知道自己的变量被修改了,所以模块化思想之前很容易造成变量命名冲突的问题 所以必须解决这种问题,通过一些方法去避免这些错误,比如:匿名函数,但匿名函数又会发生每个js文件中的作用域私有,而代码不可发生复用的问题,因此又需要想方法解决,例如: // a.js
var moudleA = (function() {
const obj = {}
const a = '我是模块A中的变量a' obj.a = a
return obj // 将匿名函数中的变量暴露出去,实现代码复用
})() // b.js
(function() {
console.log(moudleA.a) // 引用a中的变量,并且解决变量重名
})() // index.html 中同时引入a.js、b.js
并且,这种导入方式对js插入顺序依赖性很强,一般公司多人开发,不同的开发人员引入不同的js文件,插入位置错误发生的报错。
但不可否认,通过匿名函数将变量暴露出去这种方式,就是最基础的模块封装。当然现在对于前端模块化已经有了很多规范:Common.js、AMD、CMD、ES6中的Modules。
总结:
0代码复杂化带来的问题
1为什么需要模块化
2模块化方案
3es6之前的方案
4处理模块依赖,整合打包
5不仅仅能处理js,其他html,css,图片,json也可以模块化处理

什么是webpack?

简单通俗的说webpack就是一个前端自动化工具 模块 打包

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

它是依赖于node环境的

官网:

https://www.webpackjs.com/concepts/

搭建vuecli

1先安装node环境

node -v npm -v 查看版本

2新建文件夹vuecli,并初始化

npm init -y

文件夹是中文名的话,这样会报错,需要npm init回车然后填写名称,其他信息一路回车即可,然后熟悉的package.json两兄弟文件就在根目录中出来了

npm安装是缩写模式, 简单说下:

-D 为 --save-dev 开发环境中使用

-S 为 --save 生产环境中使用

-g 为 --global 全局安装





安装npm i webpack webpack-cli -D 我之前已经安装过全局的了

为啥在项目中还要安装本地webpack,而不是直接用全局的?

当你全局安装了webpack, 你使用指令webpack打包又先调用的是你全局的webpack。 毕竟你今天安装的webpack是这个版本,不能保证以后谁拿你代码一运行调用他电脑下载的webpack版本,beng,满屏飘红就出来了。因为当时做项目时的webpack版本不一样,当你克隆下来时,你就会把当时的webpack版本也克隆下来,再安装时候,就不会出现版本冲突了 所以保险点,项目都安装自己的webpack,版本不会冲突。

3测试webpack打包使用

新建文件夹dist和文件mian.js和index.html



index.html文件引入打包后的文件 命名为bundle.js如图



maian.js输入测试代码



在终端输入命名 版本不同命令输入也不同 注意

webpack main.js -o dist/bundle.js 会生成如图



测试代码也能成功



注意:此时的webpack命令是调用全局的webpack

当你安装好webpack后执行打包指令后, 执行"webpack xxxx"时要注意,此时如果你安装了全局webpack,任然调用的是你全局的而不是项目自己的,你项目调用自己的webpack指令应该是./node_modules/.bin/webpack xxxxx

为了解决该问题,我们可以添加webpack.config.js

4添加webpack.config.js文件

// webpack.config.js
const path = require("path") //node自带模块 引入路径模块
module.exports = {
entry: "./main.js", // 入口
output: {
path: path.resolve(__dirname, 'dist'), // 出口。必须为绝对路径,所以借助node的path模块 __dirname保存的是当前文件的路径
filename: 'bundle.js' // 打包后文件名
},
}
// 意思就是:我根目录有个main.js文件,里面导入了好多东西,帮我打包到我目录里面的dist文件下bundle.js文件里
// package.json
并且还需要更改一下package.json文件中的scripts属性
{
...
scripts: {
...
"build": "webpack" // build可以随便取,如: 叫xxx,终端运行 npm run xxx即可
//执行脚本"build": "webpack"时候,它会优先找本地的webpack,
//只要实在终端直接输入webpack打包都是使用的全局的,所以为了解决这个问题,用脚本这样会优先找本地的
}
...
} // 意思: 以后我直接在终端运行一个叫build的指令去调用webpack打包, 并且通过该指令, 会自动帮我们调用开发环境中的webpack打包

当运行npm run build时,webpack会看看我们根目录是不是有一个叫webpack.config.js的文件,然后读取运行其中的配置。

弄完这一步,最后将index.html中引入的main.js改为bundle.js后,我们可以愉快的将各个js文件当成模块,各种require、import、、、,尽情导入导出

比如,我这里在src文件夹中新建js文件夹,添加info.js、mainUnit.js然后再main.js中引入并使用

loader的使用

webpack并不能识别许多文件类型,我们需要通过各种各样的loader,来帮webpack识别。

接下来做css相关,图片相关的loader,新建文件如下



在main.js中引入 require("xxx.css")或者import "xxx.less",然后一运行报错

5引入css和less相关loader

进入webpack官网, 点击导航中的LOADERS,点击左边导航的样式,然后就可以根据需求对照文档安装和配置你需要的样式相关loader了

我这里安装css和less相关的loader,npm i style-loader css-loader less-loader less -D 因为loader基本用于开发环境, 所以安装一般都为--save-dev

// webpack.config.js
module.exports = {
...
module:{
rules: [
{
test: /\.css$/,
// css-loader 只负责解析css,并不负责插入样式到页面
// style-loader 负责将样式插入页面中
// 使用多个loader时,从右往左调用
use: ['style-loader','css-loader']
},
{
test: /\.less$/,
use: [{ // use中如需配置其他options 可以使用Object形式, 否则不配置可直接用Array形式,同上css-loader
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "less-loader"
}]
},
]
}
...
}

5引入图片相关loader

在网上随便找2张一大一小图片

npm install --save-dev url-loader

// webpack.config.js
module.exports = {
...
rules: [
...
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
// 当加载图片,小于limit时,会将图片编译成base64字符串形式
// 当加载图片,大于limit时,需要安装file-loader进行加载,加载图片会放入你打包输出的文件目录
limit: 8192 // 8192 / 1024 = xKB
}
}]
}
...
]
...
}

limit属性说明如上方注释,当图片小于limit设定的值时以base64字符串形式插入在打包的js中,此时没问题。

但是,一旦大于设定值,webpack会报错,需要安装file-loader,安装即可,不需要单独配置。

然后wenpack会将引入图片完整打包放入dist文件夹目录下,名称为32位hash值,并将开发环境中引用的图片路径替换为打包生成的图片,而此时index.html引用的为开发目录中(即img文件夹下)的图片,所以打包后再运行index.html发现背景图片不见了

所以这时我们需要当图片大于limit设定值时的打包后页面引入路径更改为dist/xxxxx,好的,进入webpack.config.js,在其中output属性中添加publicPath属性

npm install --save-dev file-loader

// webpack.config.js
module.exports = {
...
output: {
...
// 添加该属性,以后打包文件所有涉及到url的东西,都会自动在路径前添加 dist/
publicPath: 'dist/'
}
...
}

我们通常并不希望,所有的img全部打包在dist文件夹下,而是希望放在dist/img文件夹中,并且希望图片保持原名,但怕重名,还需要加点hash值。

因此,我们可以继续配置url-loader规则

// webpack.config.js
module.exports = {
...
rules: [
...
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 8192 ,
// 当不希望它打包直接放入dist文件中时,可以添加name属性,
// 当需要保存原名时可以添加[name]
// 当需要防止重名又不需要太长的hash值时可以添加[hash: x] x为你需要hash值位数
name: 'img/[name].[hash:8].[ext]'
}
}]
}
...
]
...
}
因为之前有publicPath配置,所以打包运行index.html页面图片引入路径仍然为dist/img/xxxx.xxx

7ES6转ES5

完成上面一步之后,领导打开他很久没更新的浏览器,发现页面并没有出来,打开控制台一看,全是ES6语法报错,然后立马说:“你这打包不对劲啊,浏览器版本一低就各种报错,我们不能保证用户都使用可以识别ES6语法的浏览器,代码应该要将老旧浏览器都兼容啊。”

好吧,满足他的需求,打开浏览器搜索babel,进入中文官网,点击设置选择Webpack,对照文档在编辑器中一顿输出。

npm install --save-dev babel-loader @babel/core @babel/preset-env

安装完成后,在webpack.config.js中添加规则:

// webpack.config.js
module.exports = {
...
rules: [
...
{
test: /\.js$/,
exclude: /node_modules/, // 排除的目录
// 使用babel-loader将ES6代码转为ES5,做浏览器兼容
// 同时需要建立.babelrc文件,调用@babel/preset-env插件将E6转为E5S
loader: "babel-loader"
}
...
]
...
}

此时,babel-loader已经可以将ES6语法识别,但是打包将ES6转ES5还需要@babel/preset-env插件,所以我们要新建一个名为.babelrc的babel配置文件使用该转译插件:

// .babelrc
{
"presets": ["@babel/preset-env"]
}

9使用Vue

正准备执行回家程序操作,领导叫住说:“项目前端框架要用vue,就用你那玩意搞,正好可以打包。”得,继续搭vue吧。

npm i vue -S

因为vue不仅是在开发环境中使用,并且打包后依然需要依赖vue,所有安装在生成环境中。

安装之后,在main.js中使用一下吧

// main.js
import Vue from "vue";
new Vue({
el: "#app",
data: {
msg: "哈哈,使用了Vue"
}
})
// 然后在index.html中使用一下
// index.html
...
<div id="app">
<h2>{{ msg }}</h2>
</div>
...

好吧,main.js中引入的vue模块,使用的是runtime-only版本的,该版本有vue运行代码,但没有编译template的代码。

那咋办,换个vue模块引入的版本呗,打开webpack.config.js。

// webpack.config.js
module.exports = {
...
// 设置模块如何被解析
resolve: {
// 当安装vue时,默认使用的是runtime-only版本,此版本只含有vue运行的代码,不包含编译template的代码
// 需要重新更换含有runtime-compiler的版本,因为runtime-complier含有complier代码可以用于编译template
// alias(别名): 用别名代替前面的路径,不是省略,而是用别名代替前面的长路径
// 如下,当main.js中import Vue from "vue"时,因为vue是别名,所以实际为import Vue from "vue/dist/vue.esm.js"
// 别名好处是webpack直接会去别名对应的目录去查找模块,减少了webpack自己去按目录查找模块的时间
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
...
}

属性解释如上图,语文好的去官方文档看,反正我是理解不了它说的啥,文档说点白话,通俗易懂不好吗。

简单说alias就是拼接导入模块的路径,emmm,还是举例吧,如下:

// webpack.config.js
...
alias: {
'vue$': 'vue/dist/vue.esm.js' // 这是别名vue
}
... // main.js
import Vue from "vue" <==> import Vue from "vue/dist/vue.esm.js" import Vue from "vue/xxx/xxx" <==> import Vue from "vue/dist/vue.esm.js/xxx/xxx"

好了,应该懂了,反正也是写我自己看的,你们不理解百度去吧。

在我这其实是将alias当成vue模块引入版本重定向,当引入vue,默认引入vue.runtime.common.js文件,而我将引入文件重定向为vue.esm.js。

我怎么知道默认引入哪个版本的?

打开node_modules/vue/package.json,查看其中main属性,就是vue模块默认引入的版本。

其他版本,在node_modules/vue/dist文件夹中。

到这一步,vue配置就完成了。

10vue中template的封装

注意代码的演变

代码抽离1

// main.js
import Vue from "vue";
new Vue({
el: "#app",
template:`<div>{{msg}}</div>`
data: {
msg: "哈哈,使用了Vue"
}
})
// 然后在index.html中使用一下
// index.html
...
<div id="app">
</div>
...

代码抽离二

 main.js
const App = {
template: `<div>{{msg}}</div>`,
data() {
return {
msg: "哈哈,使用了Vue123"
}
}
}
import Vue from "vue";
new Vue({
el: "#app",
template:`<App></App>`,
components: {
App
}
})
// 然后在index.html中使用一下
// index.html
...
<div id="app">
</div>
...

代码抽离三

 main.js
import App from './app.vue'
import Vue from "vue";
new Vue({
el: "#app",
template:`<App></App>`,
components: {
App
}
})
// 然后在index.html中使用一下
// index.html
...
<div id="app">
</div>
...
// app.vue
<template>
<div class='app'>
<div>{{msg}}</div>
</div>
</template>
<script>
export default {
name: 'app',
data() {
return {
msg: "哈哈,使用了Vue1235"
}
},
mounted() { },
watch: {},
computed: {},
methods: {},
components: {}
};
</script>
<style lang='less' scoped='scoped'>
</style>

注意 会遇到两个问题

第一

使用vue文件需要安装vue-loader

cnpm i vue-loader vue-template-compiler -D

第二

vue-loader版本问题

错误是指vue-loader在14版本以上,需要安装另外的插件

方法一:

进入package.json文件中,找到vue-loader的版本

^13.0.0指会自动匹配13.x.x中的最新版本,但是不会匹配到14.0.0

和^(插入符号)一对还有一个符号~(波浪符号)

~13.3.0指会匹配更新到13.3.x的最新版本,但不会更新到13.4.0

然后npm install

方法二:

在webpack.config.js文件中配置以下

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

plugins: [
new VueLoaderPlugin()
]

之后就可以使用vue组件 路由 进行基本的开发了

webpack-从零搭建vuecli环境的更多相关文章

  1. 以Aliyun体验机为例,从零搭建LNMPR环境(上)

    使用云服务器搭建 Web 运行环境,尤其是搭建常见的 LNMPR(Linux+Nginx+MySQL+PHP+Redis) 环境,对于开发人员是必备的职场基本技能之一.在这里,借着搭建我的" ...

  2. 以Aliyun体验机为例,从零搭建LNMPR环境(下)

    使用云服务器搭建 Web 运行环境,尤其是搭建常见的 LNMPR(Linux+Nginx+MySQL+PHP+Redis) 环境,对于开发人员是必备的职场基本技能之一.在这里,借着搭建我的" ...

  3. 通过create-react-app从零搭建react环境

    一. 快速开始: 全局安装脚手架: $ npm install -g create-react-app 通过脚手架搭建项目: $ create-react-app <项目名称> 开始项目: ...

  4. 从零搭建 vue-cli 脚手架

    前言: 用了几次 vue-cli 做 vue 项目,感觉没什么大问题,虽然也没有用 vue-router 和 vuex .但是心里一直有个梗,就是最初的目录生成和配置文件,一直没动过,也不知道具体原理 ...

  5. 使用vue+webpack从零搭建项目

    vue到现在已经成为一个热门的框架,在项目实践当中,如果想要创建一个新项目,通常都会使用vue-cli的脚手架工具,毋容置疑能够方便很多,很多东西也不需要自己亲自去配置.都知道,脚手架其实是vue结合 ...

  6. 从零搭建LNMP环境

    Linux就是环境所在的操作系统: Nginx则是一个「高性能的HTTP和反向代理服务器」,官网地址:http://nginx.org/: MySQL则是一个方便地对数据进行增删改查的数据库管理系统, ...

  7. 从零搭建 webpack3 环境 #1 - 安装使用

    目录: (1)什么是webpack (2)webpack核心概念 (3)环境安装 (4)开始使用webpack 1.什么是webpack 官网的一幅图对webpack的解释,从图中可以看出,webpa ...

  8. 从零搭建生产环境的ghost2.0博客

    当前安装过程是在ghost cli 1.9.2上的,由于ghost更新特别快,我安装我个人博客cmlanche.com的时候还是1.9.1,当时没碰到啥问题,到1.9.2就有一点点不一样了,所以要注意 ...

  9. 初探webpack之从零搭建Vue开发环境

    初探webpack之搭建Vue开发环境 平时我们可以用vue-cli很方便地搭建Vue的开发环境,vue-cli确实是个好东西,让我们不需要关心webpack等一些繁杂的配置,然后直接开始写业务代码, ...

随机推荐

  1. 爬虫日志监控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替换IP与用户 导读: 现ELK四大组件分别为:Elasticsearch(核心).logstash(处理).filebeat(采集).kibana(可视化) 在elastic官网下载 ...

  2. 搭建 Spring 源码阅读环境

    前言 有一个Spring源码阅读环境是学习Spring的基础.笔者借鉴了网上很多搭建环境的方法,也尝试了很多,接下来总结两种个人认为比较简便实用的方法.读者可根据自己的需要自行选择. 方法一:搭建基础 ...

  3. Centos-zip压缩-文件或目录-zip unzip

    zip uzip 将一般文件或者目录进行压缩或者解压,默认以 .zip为后缀名 zip 相关选项 -r 递归压缩目录 -d 从压缩包中删除指定文件 -i  压缩指定文件列表文件 -x 压缩排除指定文件 ...

  4. 玩转Libmodbus(二) 写代码体验

    libmodbus在线文档 https://www.jianshu.com/p/d93c17485c0a 原创篇 参考上一篇转载的博客,我的ubuntu上的最终生成的动态库的路径,下图所示 我的lin ...

  5. C++里的程序 GetDlgItem(IDC_EDIT_INPUTFILE) ->EnableWindow(TRUE)

    转载:https://zhidao.baidu.com/question/654519209423407765.html GetDlgItem(IDC_EDIT_INPUTFILE) ->Ena ...

  6. Tensorflow学习笔记No.2

    使用函数式API构建神经网络 函数式API相比于keras.Sequential()具有更加灵活多变的特点. 函数式API主要应用于多输入多输出的网络模型. 利用函数式API构建神经网络主要分为3步, ...

  7. centos 7 安装docker 常用指令

    什么是docker l  使用最广泛的开源容器引擎 l  一种操作系统级的虚拟化技术 l  依赖于Linux内核特性:Namespace和Cgroups l  一个简单的应用程序打包工具 docker ...

  8. 把python文件打包成可执行文件(win10实验成功)

    总是有人来找我帮看下工单状态,又懒得写页面展示出来,干脆打包成exe文件好啦 打包很简单,难点在于安装pyinstaller这个依赖包,主要是网络问题~ 我也是参考别人的博文,别人的文章写得很详细,我 ...

  9. 用composer安装captcha_src()不成功

    1,要么就是TP的框架配置有问题建议重新下载 2,要么就是下载captcha_src的语句有问题  正确的语句  composer require topthink/think-captcha 1.* ...

  10. bash 在指定目录查找包含特定关键字的文件

    比如我们要在目录/usr/local/nginx/conf/vhost/下查找baidu.com这个关键字的文件 方法1: find /usr/local/nginx/conf/vhost/ -exe ...