手把手教webpack,力求作通俗易懂的前端工具教程

浏览器使用es6代码

2.1运行第一章中的es6代码

新创建文件夹chapter2 新创建网页index.html内容以下javascript

<script>
(a)=>{alert(1)}
</script>

打开index.html查看浏览器控制台F12:css

Uncaught SyntaxError: Unexpected token =>

浏览器不支持ES6脚本语言箭头符
咱们须要能识别ES6的软件
帮助咱们把es6代码转换成es5浏览器能识别的代码html

安装第3方软件帮助咱们使用es6

2.2 安装node.js

第3方软件做为node.js模块软件包
想使用这些软件必须先安装node.js前端

2.2 安装npm

新版的node.js已经集成NPM
咱们能够经过npm下载管理全部的软件包
你们能够在windows控制台窗口输入npm -v查看当前版本vue

2.3 切换到chapter2目录 在控制台输入npm.init

做用:把当前项目配置成软件包
而且和其余软件包交互依赖关系
一直点下一步便可
node.js会在当前项目生成packgae.json
该文件咱们只须要了解如下字段配置
//做为软件包入口,当本项目做为软件包调用时java

"main": "index.js"

//本项目依赖的其余软件包node

"description":..`

//使用-dev指令 下载的软件包依赖react

devDependencies:..

2.4 经过npm安装babel命令行软件包解析es6语法

//把babale-cli安装到node全局路径上jquery

npm install -g babel-cli

//使用--save自动配packgae.json依赖关系
//而且把babel命令行程序安装到项目路径webpack

npm install --save babel-preset-es2015`

这时候你会发现你当前项目路径上出现了1个文件夹node_modules
打开看看哇塞好多文件啊这就是babel用来解析es6的全部文件
此刻说明babel已经安装好了
咱们在项目路径下创建1.js 写入如下代码

(a)=>{alert(1)}

点击windows开始运行输入cmd启动控制台
cd命令切换到当前项目路径运行:

babel 1.js --presets es2015

控制台会显示:

"use strict";
(function (a) {
alert(1);
});

咱们获得了能够在浏览器上使用的es5代码
把控制台的代码写到1.js中
修改index.html

<script type='text/javascript' src='./1.js'></script>

若是感受麻烦能够把控制台的代码写入本地硬盘文件中

babel 1.js --presets es2015 -o 2.js

修改index.html

<script type='text/javascript' src='./2.js'></script>

浏览器再也不报错

2.5 babel转换带来新的问题

babel也安装了,es6也能被babel解析成es5了
一切都那么OK
真的是这样么?咱们修改1.js

import name from './3.js'   
(a)=>{alert(name)}

通过第一章的学习上面的代码的意识是
咱们须要使用3.js中的被默认导出的变量name
当前目录下创建3.js

name="李雷"   
export default name

运行babel 编译1.js输入到2.js中

'use strict';
var _ = require('./3.js');
var _2 = _interopRequireDefault(_);
function _interopRequireDefault(obj)
{ return obj && obj.__esModule ? obj : { default: obj }; }
(function (a) {
alert(1);
});

打开index.html点击F12查看控制台

Uncaught ReferenceError: require is not defined

又出错了!没办法解析require

好麻烦啊不想继续看了!前端搞这么复杂

坚持下 不用记下来
能看懂配置文件就能够

咱们须要能解析require命令的软件!

2.6 require的效果合并js文件

想象若是1.js是以下这样的就行了

name="李雷"  //来自3.js中的变量定义
(a)=>{alert(name)}  //原来1.js中代码定义

没错咱们须要把1.js和3.js这两个文件合并到一块儿
这样咱们就能在1.js中使用name(来自3.js中的name)变量了

2.7 在当前项目(chapter2文件夹)安装webpack,解析require指令

npm install webpack --save

点开package.json看看

"dependencies": {
     "babel-preset-es2015": "^6.22.0",
      "webpack": "^2.2.1"
      }

说明目前项目webpack引用成功

2.8 配置webpack

在当前项目下创建 webpack.config.js

var webpack =require('webpack');
     var path =require('path')
     module.exports = {
     entry: {
     //要打包的入口文件  
     //若是不写main默认会生成main文件
     main:'./1.js',
     //显示指定了name='index'
     //若是取消了注释,entry包括2个属性 main和index会分别把1.js和2.js打包2个文件
    //index:'2.js',
     },
    output: {
    //打包文件之后生成的新的文件的地址
     path: path.resolve(__dirname,'build'),
    //打包文件之后生成的新的文件名称
    filename:'[name].bundle.js',
    //静态资源文件好比图片等被打包之后的资源路径
    publicPath:'http://127.0.0.1'
    },
    module: {
    loaders: []
    },
    plugins:{}
    }

2.9 运行webpack

在windows命令行里切换到当前项目输入webpack
查看当前目录出现了build文件夹
在build文件夹中创建index.html

<script type='text/javascript' src='./main.bundle.js'></script>

里面看到webpack新生成的index.bundle.js
点击index.html
点击F12查看控制台发现。。竟然报错了

Uncaught SyntaxError: Unexpected reserved word

原来不识别箭头符号
咱们之前安装的babel-cli是控制命令行程序
须要用户手动进入控制台输入babel命令才能触发es6转换
如何让webpack也能使用babel指令?

2.10 让webpack使用babel,安装webpack版本babel插件

npm install babel-loader    
npm install babel-preset-es2015 --save    
npm install babel-core --save

修改webpack.conf.js配置插件

var webpack =require('webpack');
var path =require('path')
module.exports = {
 entry: {
 main:'./1.js'
      },
 output: {
  //打包后的文件路径
  path: path.resolve(__dirname,'build'),
  //打包后的文件名字
  filename:'[name].bundle.js',
  //使用import导入静态资源好比jpg
  //会自动添加前缀
  // import './1.jpg'
  //http://127.0.0.1/1.jpg
  publicPath:'http://127.0.0.1/'
     },
 module: {
   loaders: [
              {
          //匹配该路径下的全部文件使用对应的加载器
                  test: path.join(__dirname, './'),
         //使用babel插件  
          loader: 'babel-loader' ,
          query: {
         //使用es6转换
            presets: ['es2015']
         }
   }
   ]
   },
   plugins:{}
   }

命令行切换到项目路径使用webpack命令
会提示生成 main.bundle.js
页面引入 main.bundle.js
看看效果

还有其余的webpack相关loader插件么?

2.11 css-loader

给input添加css样式
项目目录新建文件loader.js文件 咱们准备操做dom

var input = document.createElement("input");
input.setAttribute("class",'input');
var loader  =document.getElementById('loader')
loader.appendChild(input)

项目目录 创建input.css

.input{width:1000px}

项目目录下切换到build文件夹 修改index.html

<div id='loader'>
</div>
<script type="text/javascript" src="./main.bundle.js"></script>

考虑本页面index.html如何要引入input.css
方式1:本页面引入input.css文件
手动复制input.css文件到build文件夹下
优势:方便 可视化
缺点1:使用css文件须要在html页面导入 浪费网络请求
缺点2:build文件夹下须要有input.css,但是我不想把css文件放这里
方式2:把css压缩到js文件中
优势1:把css文件 把css合并到index.bundle.js中 节省流量
优势2:build目录不须要再手动复制input.css文件
缺点:css被压缩到js文件中 再也不可视化
采用方式2

npm install css-loader --save

修改webpack.conf.js

loaders: [
{
  test: path.join(__dirname, './'),   
  loader: 'babel-loader' ,
  query: {
  presets: ['es2015']
         }
},
{
//只要被编辑的js文件,使用了import或者require指令发现".css"结尾  
//都会执行对应的loader   
  test: /\.css$/,
>     //添加对应的loader 要写上style-loader和css-loader哦
//后面的importLoaders=1表示执行顺序 用数字大小判断前后执行
loader: 'style-loader!css-loader?importLoaders=1'
 },

此时的webpack.conf.js的配置以下

var webpack =require('webpack');
var path =require('path')
module.exports = {
     entry: {
     main:'./loader.js'
      },
     output: {
     path: path.resolve(__dirname,'build'),
     filename:'[name].bundle.js',
     publicPath:'http://127.0.0.1/'
     },
     module: {
     loaders: [
     {
     test: path.join(__dirname, './'),
     loader: 'babel-loader' ,
     query: {
     presets: ['es2015']
     }
     },
     {
     test: /\.css$/,
     loader: 'style-loader!css-loader?importLoaders=1'
          },
     ]
     },
     plugins: []
     }

如何把css打包到js文件中

//使用导入指令 webpack能够自动处理该js和css合并
import './input.css';
var input = document.createElement("input");
var loader  =document.getElementById('loader')
input.setAttribute("class",'input');
loader.appendChild(input)

打包:进入项目目录运行webpack loader.js
导入编译后的mian.bundle.js
点开index.html
看看效果

2.12 url-loader

上面的css-loader能够把css文件合并到js文件中
如何把图片打包到js文件中呢?
采用url-loader

npm install url-loader --save

修改webpack.conf.js 添加对应的loader``

{
test: /\.jpg$/,
//注意该项loader必须加[]不然会报错
//变量介绍
//[ext]:匹配到的文件扩展名 好比jpg等等
//[path]:使用import指令导入的图片路径
//好比import img1 from './images/1.jpg'
//那么[path]='images'
//[name]='文件名称'
//[hash]='md5编码'
//name:使用该loader生成的文件名字
//limit:指定字节大小 小于这些字节的图片被强制转换成base64
loader: ['url-loader?limit=10000&name=[path][name].[ext]?[hash]'],
},

问题1:使用如下loader会如何处理图片

`loader: ['url-loader?limit=10000&name=[path][name].[ext]?[hash]']`

问题2:小明配置好了loader开始在代码中使用

import './input.css'
var input = document.createElement("input");
input.setAttribute("class",'input');
var loader  =document.getElementById('loader')
loader.appendChild(input)
var img=document.createElement("img");
//代码中使用图片url-loader处理该图片
img.src="./images/1.jpg";
loader.appendChild(img)

请问小明上述操做是否正确?可否正确使用url-loader处理图片

2.13 file-loader

npm install file-loader --save

file-loader用于把文本文件或者图像合并到js文件中作处理
其实用处不大,文本自己就能够定义在js文件中,若是要处理图像可使用url-loader

2.14 image-webpack-loader

npm installimage-webpack-loader --save

用于压缩图片,图片优化等
配置信息以下

{
//该表达式使用多个loader  
test: /\.(png|jpe?g|eot|svg|ttf|woff2?)$/,  
loader:  ['file-loader?digest=hex&name=[hash].[ext]',
 'image-webpack-loader?bypassOnDebug&optimizationLevel=7&interlaced=false'
]},

loader配置优化URL参数

2.15 中的loader配置的URL信息太长,咱们优化下

使用query表示查询参数

{
//该表达式使用多个loader  
test: /\.(png|jpe?g|eot|svg|ttf|woff2?)$/,  
loaders:[
{loader:file-loader,
  query:{
   digest:hex,
   name:[hash].[ext]
       }//end query
       },//end file-loader
{loader: 'image-webpack-loader'
  query: {
    progressive: true,
    optimizationLevel: 7,
    interlaced: false,
    pngquant: {
      quality: '65-90',
        speed: 4
      }
 }////end img-loader

]},

使用第3方类库

2.16 使用jquery

npm install jquery --save

新创建jquery.js
代码以下

import './input.css';
import $ from 'jquery';
var input = $("<input class='input' />");
var loader  =$('#loader')
console.log($)
loader.append(input)
loader.append(input)

配置webpack.conf.js入口文件为jquery.js
命令行运行webpack jquery.js 启动编译
引入编译文件 点开index.html

问题3:请问会上述代码会显示几个input? 本问题和本章无关,你们看到这里也很累了~作下测试看看 ?
问题4: 控制台打印出来了$ 是jquery,那么引用成功了么?

2.17 使用基于jquery的插件

项目的build文件夹下新建jquery-plus.js

//该插件:jquery对象调用message()会弹出提示
 (function($){
 $.extend({
 message:function(message){
 alert(message);
 }
 });
 })(jQuery);

修改index.html

<div id='loader'>
 </div>
 <script type="text/javascript" src='./main.bundle.js?v=4'></script>
 <script src="./jquery-plus.js"></script>
 修改jquery.js
 import './input.css';  
 import $ from 'jquery';  
 var input = $("<input class='input' />");  
 var loader  =$('#loader')  
 console.log($)  
 loader.append(input)  
 loader.append(input)  
 $.message('1');  
 编译jquery.js,点开index.html

控制台成功打印了$是jquery
可是调用message的时候提示

会提示`Uncaught TypeError: undefined is not a function`   
 Uncaught ReferenceError: jQuery is not defined`   

 请思考问题4

2.18 调用jquery插件出错缘由

上面定义的jquery插件须要依赖window.jquery ,window.$
咱们使用import指令导出的jquery或者$只再当前js文件做用域内生效
(在每一个js文件内生成了闭包 外部其余文件没办法访问到里面的内容)
致使jquery-plus.js中没办法获取到$
咱们须要把import导入的jquery赋值给windows
项目路径新建文件jquery-core.js
该js文件用于给windows相关的jquery赋值

import $ from 'jquery'
 window.$ = $
 window.jQuery = $
 /export指令请参考第一章内容 使用es6编写代码
 export default $

把jquery-plus.js复制到项目目录(原来在打包的build目录) 内容

function($){
 $.extend({
 message:function(message){
 alert(message);
 }
 });
 })(jQuery);

修改项目路径下的jquery.js

import './input.css';
 import $ from './jquery-core.js';
 import  plus from './jquery-plus.js'
 var input = $("<input class='input' />");
 var loader  =$('#loader')
 console.log($)
 loader.append(input)
 loader.append(input)
 $.message(1)
 编译打包jquery.js
 webpack jquery.js
 index.html引入打包后的js文件
 点击index.html看看效果

上面的使用jquery方案必须熟练

之后在react或者vue或者相似的框架使用webpack打包的项目中  
 若是想使用相似jquery这样的第3方库 须要这样添加

2.19 使用webPack动态热处理

上面的全部教程例子都是须要运行如下命令行

webpack 要打包的js文件    
 而后在手动点击index.html   
 很麻烦,webpack帮咱们提供了方便的操做

安装,配置webpack-dev-server

npm install webpack-dev-server

配置webpack.conf.js
在module.exports中添加新的属性

devServer:{
 //history API,若是设置为true,全部的跳转将指向index.html  
 //开发单页应用的时候须要配置  
 //若是不配置:  
 //访问127.0.0.1/gift  
 //会打开WEB服务器上的gift资源路径下的index.html  
 //在单页应用中 gift表示模块路径
 //即访问127.0.0.1/gift   
 //web服务器会把请求转发到127.0.0.1/index.html上
 //等价于访问127.0.0.1/index.html#gift
 //咱们须要在服务器配置url重写,即开启apache .htaccess
 //配置了此项,咱们无需配置服务端,webPack会自动帮咱们配置
 historyApiFallback:true,
 //定义web服务器加载首页的路径,去这个路径下加载index.html
 contentBase:'./build',
 //自动刷新机制 inline,推荐使用inline模式
 //开启之后contentBase下的index.html中必需要引入
 //<script  src="http://localhost:9090/webpack-dev-server.js"></script>    
 //利用webSocket和webpack-dev-server通讯  
 //webpack-dev-server后端文件变化 直接推送到浏览器刷新页面  
 //开启inline访问路径是127.0.0.1:9090/index.html
 //若是关闭 inline:false  
 //刷新模式改变成iframe模式
 //访问路径http://localhost:9090/webpack-dev-server/index.html
 inline:true,
 port:9090 //端口你能够自定义
 },
 修改plugins
 plugins: [
 new webpack.HotModuleReplacementPlugin(),
 new webpack.NoEmitOnErrorsPlugin(),
 ]

此时webPack.conf.js配置以下

var webpack =require('webpack');
 var path =require('path')
 module.exports = {
 devServer:{
 //history API,若是设置为true,全部的跳转将指向index.html  
 //开发单页应用的时候须要配置  
 //若是不配置:  
 /访问127.0.0.1/gift  
 //会打开WEB服务器上的gift资源路径下的index.html  
 //在单页应用中 gift表示模块路径
 //即访问127.0.0.1/gift   
 //等价于访问127.0.0.1/index.html#gift
 //咱们须要在服务器配置url重写,即开启apache .htaccess
 //配置了此项,咱们无需配置服务端,webPack会自动帮咱们配置
 historyApiFallback:true,
 //定义web服务器加载首页的路径,去这个路径下加载index.html
 contentBase:'./build',
 //自动刷新机制 inline
 //利用webSocket和webpack-dev-server通讯  
 //webpack-dev-server后端文件变化 直接推送到浏览器刷新页面  
 //开启inline访问路径是127.0.0.1:9090/index.html
 //若是关闭 inline:false  
 //刷新模式改变成iframe模式
 //访问路径http://localhost:9090/webpack-dev-server/index.html
 inline:true,
 port:9090 //端口你能够自定义
 },
 entry: {
 main:'./jquery.js'
 },
 output: {
 path: path.resolve(__dirname,'build'),
 filename:'[name].bundle.js',
 publicPath:'http://127.0.0.1/'
 },
 module: {
 loaders: [
 {
 test: path.join(__dirname, './'),
 loader: 'babel-loader' ,
 query: {
 presets: ['es2015']
 }
 },
 {
 test: /\.css$/,
 loader: 'style-loader!css-loader?importLoaders=1'
 },
 {
 test: /\.jpg$/,
 loader: ['url-loader?limit=10000&name=[path][name].[ext]?[hash]'],
 },
 ]
 },
 plugins: [
 new webpack.HotModuleReplacementPlugin(),
  new webpack.NoEmitOnErrorsPlugin(),
 ]
 }

修改项目下build文件夹index.html

<script src="http://localhost:9090/webpack-dev-server.js"></script>
 <script>
 //用于webSocket推送刷新页面
 if(module.hot) { module.hot.accept() }
 </script>
 <div id='loader'>
 </div>
 <script type="text/javascript" src="./main.bundle.js"></script>

命令行启动webpack-dev-server

修改package.json 添加如下属性 "scripts": { "start1": "webpack-dev-server --inline --watch" }, 在命令行输入npm run start1 访问127.0.0.1:9090 随意修改jquery.js看看热更新效果

相关文章
相关标签/搜索