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

浏览器使用es6代码

2.1运行第一章中的es6代码

新建立文件夹chapter2 新建立网页index.html内容如下


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

Uncaught SyntaxError: Unexpected token =>   

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

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

2.2 安装node.js

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

2.2 安装npm

新版的node.js已经集成NPM
我们可以通过npm下载管理所有的软件包
大家可以在windows控制台窗口输入npm -v查看当前版本

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

作用:把当前项目配置成软件包
并且和其他软件包交互依赖关系
一直点下一步即可
node.js会在当前项目生成packgae.json
该文件我们只需要了解以下字段配置
//作为软件包入口,当本项目作为软件包调用时

"main": "index.js"   

//本项目依赖的其他软件包

"description":..`   

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

devDependencies:..   

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

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

npm install -g babel-cli    

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

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

   

如果感觉麻烦可以把控制台的代码写入本地硬盘文件中

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

修改index.html

   

浏览器不再报错

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

    

里面看到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

考虑本页面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 = $("");
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

 
修改jquery.js import './input.css'; import $ from 'jquery'; var 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 = $("");
 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中必须要引入
 //    
 //利用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

 
 
 

命令行启动webpack-dev-server

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

版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

转载于:https://my.oschina.net/u/2508417/blog/854341

你可能感兴趣的:(webpack,前端,操作系统)