美文网首页webpack
如何使用Webpack进行打包?

如何使用Webpack进行打包?

作者: 李悦之 | 来源:发表于2017-08-18 19:40 被阅读825次
    一、理解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,不想写了,文档上写的很清楚呢

    相关文章

      网友评论

        本文标题:如何使用Webpack进行打包?

        本文链接:https://www.haomeiwen.com/subject/qzinrxtx.html