如何使用Webpack进行打包?

一、理解Webpack的打包过程

1.创建一个test目录并进入

mkdir test && cd test  
  1. npm 初始化,生成package.json文件
npm init -y  //如果不加-y就一路回车
  1. 安装webpack
npm install webpack --save-dev   //会安装到test目录下node_modules目录下面

4.在根目录下新建一个hello.js文件并用webpack进行打包

touch hello.js 
./node_modules/.bin/webpack hello.js hello.bundle.js

这样就完成了一次最简单的打包,./node_modules/.bin/webpack就是安装在test目录下的webpack命令。虽然完成了一次极简的打包,但是这样是远远不够的。

5.试着多添加一个world.js文件

world.js

export { world }   //写一个函数并将它暴露出来
function world() {
  alert('我是world')
}

hello.js内容

require('./world.js')  //引入world.js
world() 在hollo.js中执行world.js中的函数

运行打包命令

./node_modules/.bin/webpack hello.js hello.bundle.js

成功打包。这样,hello.js就是入口文件,其它文件诸如world.js都通过ES6/Commom.js/AMD语法引入到这个入口文件里,然后打包成一个文件hello.bundle.js文件。这样,就可以实现模块化编程,不仅仅是JS文件,CSS、SASS、LESS、VUE等都可以引入到入口文件里,再进行打包,这就是模块化,而需要做的,就是安装针对不同类型的loader。

二、配置文件

上面写的内容主要是理解,接下来为了更好地发挥webpack的功能,我们重新整理和配置webpack的文件

1. 删除之前根目录下除了node_modules和json文件之外的所有其它文件。
2. 在test目录下新建src目录,所有的源码都放在这里,在src目录下,分别新建script目录和style目录用来存放
js文件和样式文件。

3. 在test目录下新建dist目录,作为打包以后的输出文件的存放目录。
4. 在test目录下新建index.html文件,用script标签引入dist/bundle.js文件。
5. 在test目录下新建webpack.config.js作为配置文件。

三、配置webpack.config.js

webpack.config.js是webpack的配置文件,在我们运行webpack打包命令的时候,它会自动去寻找这个文件,然后根据这个文件里的具体配置来进行打包。

  1. webpack.config.js内容
var path = require('path')                                      //引入path

module.exports = {                                              //注意这里是exports不是export
  entry: './src/script/main.js',                                 //入口文件
  output: {                                                       //输出文件
    path: path.resolve(__dirname,'dist'),                      //输出文件的目录
    filename: 'bundle.js'                                        //输出文件的名称
  }
}

运行打包命令

./node_modules/.bin/webpack                     //有了配置文件以后直接输入命令即可,它会自动找配置文件

如果我们有多个配置文件,比如还有一个webpack.dev.config.js文件,webpack默认运行的文件是webpack.config.js,但是想要让它运行另一个配置文件应该怎么办呢?办法如下:

./node_modules/.bin --config webpack.dev.config.js               //使用--config参数就行了

这里还有一个问题,就是每次运行webpack命令,都要写./node_modules/.bin/webpack这样一长串,可不可心简化呢?当然是可以的。只需要package.json文件里写一个script就行了。

屏幕快照 2017-08-18 上午12.03.43.png

这样,只要我们运行npm build就相当于执行了webpack命令,而npm会非常智能地从node_modules里找这个命令。
当然,这个命令还可以继续优化。我们发现,每次打包以后,bundle.js的文件都会非常大,如果让它变小呢?那就使用./node_modules/.bin/webpack -p这个命令 -p就是出版的意思,这样它就会自动压缩,所以我再改一下package.json文件。

屏幕快照 2017-08-18 上午12.09.08.png

这样,再次运行npm run build就相当于运行了./node_modules/.bin/webpack -p了。我们可以明显地发现,bundle.js的体积被压缩了。

  1. 运行打包命令时可以使用的其它参数
./node_modules/.bin/webpack --progress --display-modules --display-reason --colors  //看到过程、显示模块、显示打包原因、看到颜色变化
四、多页面进行打包时webpack.config.js的配置方法
var path = require('path')

module.exports = {                            //注意这里是exports不是export
  entry: {                                             //这里entry写成了对象,这样的话就可以写多个入口文件分别打包
    main: './src/script/main.js',       
    a: './src/script/a.js'
  },
  output: {
    path: path.resolve(__dirname,'dist'),
    filename: '[name]-[hash]-bundle.js'                  //这里[name]-[hash]-bundle.js通过name和hash来区分不同的
  }
}

这样的话,就可以把多个入口文件打包成不同文件名和不同哈希值的JS文件,并且都放在dist目录下。

但是这里却有一个很大的问题,那就是每次打包都会新生成一次打包文件,这些文件如何放到HMTL里呢?总不能每打一次包就手动更改一次吧?为了解决这个问题,就需要使用一个插件:html-webpack-plugin。用这个插件动态生成HTML文件并且把相应的打包文件放到里面。

npm安装插件

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

改写webpack.config.js文件:

var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin')                //Common.js语法引入插件

module.exports = {             //注意这里是exports不是export
  entry: {
    main: './src/script/main.js',
    a: './src/script/a.js'
  },
  output: {
    path: path.resolve(__dirname,'dist'),
    filename: '[name]-[hash]-bundle.js'
  },
  plugins: [                                             //使用插件
    new HtmlWebpackPlugin({                              //因为要生成两个不同的html文件,所以要new两次
      filename: 'index.html',                                //filename指定生成html文件名
      template: 'index.html',                               //template指定打包参照的模板
      chunks: ['main']                    //chunks参数指定要把哪个入口文件打包后嵌入到HTML里,可以是一个也可以是多个
    }),
    new HtmlWebpackPlugin({
      filename: 'a.html',
      template: 'a.html',
      chunks: ['a']
    })
  ]
}

运行打包命令后,我们可以看到在dist目录下,生成两个打包的JS文件和HTML文件,而打开a.html里面就内嵌了a开头的打包的js文件。而参照的template就是根目录下index.html和a.html文件。

屏幕快照 2017-08-18 上午9.51.19.png
五、使用loaders来加载资源(这一部分很重要)

webpack可以将各种各样的资源,包括CSS/SASS/LESS/PNG/JPG/JPEG等都进行打包,只是它需要应用不同的loader。

安装loaders

npm install --save-dev babel-loader babel-core babel-preset-es2015  //这是将es6转换为es5所必须的
npm install --save-dev postcss-loader css-loader style-loader autoprefixer cssnano    //安装相应loader和插件
npm install --save-dev less less-loader    //安装less和less-loader
npm install --save-dev sass sass-loader  //安装sass和sass-loader
npm install --save-dev file-loader url-loader

在使用postcss-loader的时候有点复杂,先在要目录下新建一个postcss.config.js文件,如下:

module.exports = {
  plugins: {                                //这里可以使用各种各样的插件,postcss非常强大
    'autoprefixer': {},                 //这个插件用来给CSS文件添加前缀
    'cssnano': {}                        //这个插件用来压缩CSS
  }
}

在webpack.config.js的配置文件配置loader:

var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {             //注意这里是exports不是export
  entry: {
    main: './src/script/main.js',
    a: './src/script/a.js'
  },
  output: {
    path: path.resolve(__dirname,'dist'),
    filename: '[name]-[hash]-bundle.js'
  },
  module: {
    loaders: [                                                    //loaders在这里
      { test: /\.js$/,                                             //针对js文件里可能出现的es6语法转换
        exclude: path.resolve(__dirname, 'node_modules'),         //不检测的路径,这里用path改为了绝对路径
        include: path.resolve(__dirname, 'src'),                  //检测的路径,注意这里是绝对路径,写相对路径会报错。
        loader: 'babel-loader',
        query: {
          presets: ['es2015']                   //这个参数可以写在这里,也可以在根目录下建一个.babelrc或者写在package.json里
        } 
      },
      {
        test:/\.css$/,
        use: [                                                                   //这里写法和上面不太一样,但是效果相同
          {loader: 'style-loader' },                                     //效果依然是从右往左,先是postcss-loader
          {loader: 'css-loader', options: {importLoaders: 1}},     //这个css-loader写了一个参数,是为了让@import 进来的CSS也同样可以通过postcss-loader
          {
            loader: 'postcss-loader',
            options: {
              plugins: (loader) => [
                require('autoprefixer')({ broswers: ['last 5 versions'] }),     //这里给插件添加参数
                require('cssnano')()
              ]
            }
          }
        ]
      },
      {
      test: /\.less$/,
      loader: 'style-loader!css-loader!postcss-loader!less-loader'     //这里postcss-loader必须放在less和css之间
      },
      {
      test: /\.scss$/,
      loader: 'style-loader!css-loader!postcss-loader!sass-loader'
      },
      {
        test: /\.(jpg|png|gif|svg$)/,           //对于一些图片文件的加载,可以使用file-loader和url-loader
        use: [                                 //对于CSS中的url可以正常加载没问题,对于组件里的就需要用到require语法
          {                                     //如果是在根目录index.html那个img的话,那就没办法了,要么转换成背景图片,要么就使用import导入到入口的JS文件里,再用JS方法加上去
            // loader: 'file-loader',
            loader: 'url-loader',          //url-loader和file-loader的区别在于,可以指定一个limit参数,小于它就用base-64位编码
            options: {
              limit: 200000,
              // name: 'images/[name].[ext]',
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      chunks: ['main']

    }),
    new HtmlWebpackPlugin({
      filename: 'a.html',
      template: 'a.html',
      chunks: ['a']

    })
  ]
}

对于index.html里图片url路径的问题,要么转化成背景图片,要么import到入口JS文件里再用JS的办法添加,其它没有办法。

六、最后,还有一个server和watch,不想写了,文档上写的很清楚呢
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容

  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,140评论 7 35
  • 写在开头 先说说为什么要写这篇文章, 最初的原因是组里的小朋友们看了webpack文档后, 表情都是这样的: (摘...
    Lefter阅读 5,273评论 4 31
  • 最近在学习 Webpack,网上大多数入门教程都是基于 Webpack 1.x 版本的,我学习 Webpack 的...
    My_Oh_My阅读 8,166评论 40 247
  • GitChat技术杂谈 前言 本文较长,为了节省你的阅读时间,在文前列写作思路如下: 什么是 webpack,它要...
    萧玄辞阅读 12,674评论 7 110
  • 早安,孩子们!今天是7月20日。今天我们跟着一只飞盘去冒险。它经历了些什么?最后选择做回飞盘,它为什么快乐? 罗强...
    银杏儿_9fbc阅读 2,815评论 0 1