webpack使用小记

前言

webpack是目前前端开发必不可少的一款模块加载器兼构建工具,它能极其方便的处理各种资源的打包和使用, 让前端开发获得与后端开发几乎一致的体验。

webpack特点

  • webpack 是以 commonJS 的形式来书写脚本的,可以直接使用 require或者import(es6写法,配置babel支持) 的写法来引入各模块
  • webpack除了支持编译js为模块外,webpack也支持编译html,css, js, less, jsx,图片等非常多的资源为模块,只需要配置一下对应的加载器即可
  • webpack还可以直接替代能替代不少原本属于gulp的工作,比如打包,压缩,混淆,图片转base64等
  • webpack提供了配套的dev-server,并且支持热更新(配置热更新插件),无须自己用nodejs配置一个热更新httpServer,开发调试非常便捷
  • webpack支持自定义插件,可以很容易的扩展特定的功能,比如目前如日中天的react,就有一款react-hot-loader插件来支持react项目的热更新

如何使用webpack

  • 在项目中安装webpack

    npm install webpack --save-dev  
  • 在项目的根目录新建一个 webpack.config.js 文件,加入各配置项
  • 使用webpack命令行运行指令,比如 webpack --display-error-details,对项目进行编译打包

webpack 2常用配置参数介绍

// file -> webpack.config
var webpackConfig = {
    // 需要编译的入口文件配置
    entry: {
        index: ‘./app/entry/index.js‘,    // index 指模块的名称,其他配置项加入模块时需要指定模块名称
        login: [ ‘./app/entry/login.js‘ ],    // ./src/js/page/login.js 指的是该模块的文件的路径
        useinfo: [ ‘./app/entry/userinfo.js‘, ‘./app/entry/user.js‘ ]  // 可以将二个文件合并作为一个入口
    },

    // 编译完的入口文件输出配置
    output: {
        // 指定编译模块文件的存放目录(/build/js/),不能用于html中的文件引用。
        path: path.resolve(__dirname, "build"), //如使用webpack-dev-server, 则该目录的位置应设置为为虚拟web服务器的根目录

        // 配置文件在html中引用的根路径,会影响在html中模块的引用路径
        publicPath: "/assets/",
        //publicPath: "http://cdn.com/assets/",//你也可以加上完整的url,效果与上面一致(不需要修改index.html中引用bundle.js的路径,但发布生产环境时,建议使用HtmlWebpackPlugin插件批量修改引用地址为cdn地址)。

        // filename 指输出的每个js模块名称及存放路径的定义,会影响在html中模块的引用路径
        filename: "js/bundle.js",  // 单页应用只有一个入口文件时使用,在html页面上通过<script src="/js/bundle.js"></script>引用入口模块
        filename: "js/[name].js",  // 传统多页应用有多个入口文件时使用,[name] 代入entry配置中的任意一项模块的名称,例如:index, 在不同的页面上引用不同的入口,例如在index.html页面上通过<script src="/js/index.js"></script>引用入口模块
        filename: "js/[hash]/[chunkhash].js",  // 为生产环境实现前端静态资源增量更新时使用,[hash]是根据每次编译后项目总体文件的hash值, [chunkhash]是根据每个模块内容计算出的hash值。

    },

     // 模块配置
     module: {
        // 模块处理规则(包括配置模块加载器,模块编译解析规则等等)
        rules: [
          // es6的js文件使用 babel-loader 来处理,转换成es5
          {
            // 匹配的模块文件范围
            test: /\.js$/,

            // 包括哪些范围
            include: [
              path.resolve(__dirname, "app")
            ],

            // 排除哪些范围
            exclude: [
              path.resolve(__dirname, "app/demo-files")
            ],

            // 使用多个插件,及指定插件配置
            use: [
                 // "babel-loader",         // 不指定插件配置的方式
                 {
                    loader: "babel-loader", // 指定插件配置的方式,注:babel的配置建议使用.babelrc来配置
                    options: {
                      presets: ["es2015"]
                    },
                 },

                 // 如使用react-hot-loader,则需要在这里加入
                 ‘react-hot-loader/webpack‘
            ]
          },

          // 图片文件使用 url-loader 来处理,小于8kb的直接转为base64
          {
              test: /\.(png|jpg|gif)$/,
              use: [
                  {
                      loader: ‘url-loader‘,
                      options: {
                          limit: 8192,
                          // name 指输出的每个图片模块名称的路径定义
                          name: ‘images/[name]-[chunkhash].[ext]‘,   //[name]指图片文件名, [ext]指图片的后缀名称
                      },
                  },
              ],
          },

          // less文件使用style-loader, css-loader, less-loader来处理
          {
              test: /\.less$/,
              use: [
                  ‘style-loader‘,
                  ‘css-loader‘,
                  ‘less-loader‘,
                  extractTextPlugin.extract([‘style‘,‘css‘, ‘less‘])     //
              ],
          },

          // pcss文件使用style-loader, css-loader, postcss-loader来处理
          {
              test: /\.pcss$/,
              use: [
                  ‘style-loader‘,
                  ‘css-loader‘,
                  {
                      loader: ‘postcss-loader‘,
                      options: {
                          plugins: function () {
                              return [
                                  require(‘postcss-import‘)(),      // 在@import css文件的时候让webpack监听并编译
                                  require(‘precss‘),                // 类似scss的语法,实际上如果只是想用嵌套的话有cssnext就够了
                                  require(‘postcss-cssnext‘),       // cssnext可以让你写CSS4的语言,并能配合autoprefixer进行浏览器兼容的不全,而且还支持嵌套语法
                              ];
                          },
                      },
                  },
              ],
          }
        ]
     },    

     // 配置如何访问模块
     resolve: {
         // 配置查找npm依赖包的路径规则,默认是查找node_modules
         modules: [
          "node_modules",
          path.resolve(__dirname, "app")
        ],

        // 使用了哪些文件后缀名
        extensions: [".js", ".json", ".jsx", ".css"],

        // 模块路径的别名配置,将冗长的模块引用路径配置成简短的模块别名
        alias: {
            "third": path.resolve(__dirname, "app/third"),              // 引用module,使用‘third/module‘
            "module": path.resolve(__dirname, "app/third/module.js"),   // 引用module,使用‘module‘
        }
     },

     // 性能配置
     performance: {
         // 当资源不符合性能规则时,以什么方式进行提示, 默认值为waring
         hints: "warning", // 输出警告的方式,推荐在开发环境下使用
         hints: "error", // 输出错误的方式,推荐在生产环境下使用
         hints: false, // 关闭提升

         maxAssetSize: 200000, // 单个资源允许的最大文件容量,单位:字节,默认250kb
         maxEntrypointSize: 400000, // 单个入口模块引用的所有资源的最大文件容量,单位:字节,默认250kb

         // 控制哪些文件需要进行性能检测,默认值如下
         assetFilter: function(assetFilename) {
              return !(/\.map$/.test(assetFilename))
         },
         // 控制只有css与js文件需要进行性能检测
         assetFilter: function(assetFilename) {
           // Function predicate that provides asset filenames
           return assetFilename.endsWith(‘.css‘) || assetFilename.endsWith(‘.js‘);
         }
     },

     // 通过增加输出信息的方式为浏览器开发者工具增强调试
     devtool: "source-map", // 为模块生成单独的source-map文件,会大幅影响编译速度
     devtool: "eval", // 不生成sourceMap, 但是命名模块,编译速度最快.
     devtool: "cheap-module-eval-source-map", // 开发环境推荐
     devtool: "cheap-module-source-map", // 生产环境推荐 

     // 使用 cheap 模式可以大幅提高 souremap 生成的效率。大部分情况我们调试并不关心列信息,而且就算 sourcemap 没有列,有些浏览器引擎(例如 v8) 也会给出列信息。
     // 使用 eval 方式可大幅提高持续构建效率。官方文档提供的速度对比表格可以看到 eval 模式的编译速度很快。
     // 使用 module 可支持 babel 这种预编译工具(在 webpack 里做为 loader 使用)。
     // 使用 eval-source-map 模式可以减少网络请求。这种模式开启 DataUrl 本身包含完整 sourcemap 信息,并不需要像 sourceURL 那样,浏览器需要发送一个完整请求去获取 sourcemap 文件,这会略微提高点效率。而生产环境中则不宜用 eval,这样会让文件变得极大。

     // 根路径,默认值是__dirname,基于这个路径去处理配置的模块入口和加载器
     context: __dirname, // 默认值

     // 编译环境,默认值是web
     target: "web", // 浏览器编译环境

     // 将配置的模块从bundle文件中分离出来,模块可以是 CommonJS, AMD, global and ES2015 modules 4种类型
     externals: {
       react: ‘react‘
     },

     // 配置在编译时输出相关信息
     stats: { //object
         assets: true,
         colors: true,
         errors: true,
         errorDetails: true,
         hash: true,
         // ...
    },

     // 配置开发服务器
     // 要使之生效,还需要同时在entry的每一项之前加入‘webpack-dev-server/client?http://{指定的IP}:{指定的端口}‘,
     // ‘webpack/hot/log-apply-result‘与‘webpack/hot/only-dev-server‘
     // 如使用了react-hot-loader, 则还需要加入‘react-hot-loader/patch‘
     devServer: {
         // 配置代理服务器
         proxy: {
           ‘/api‘: ‘http://localhost:3000‘ // 访问路由/api,会转发到localhost:3000的地址去
         },
         contentBase: [ path.resolve(__dirname, "build"), path.resolve(__dirname, "mock") ], //  静态资源路径,需要配置编译后的模块文件存放的路径(同output中的path),也可以在这里配置其他的,比如mock文件存放的路径
         compress: true, // 是否开启压缩
         historyApiFallback: true, // true for index.html upon 404, object for multiple paths
         hot: true, // 是否开启热更新,需要配置HotModuleReplacementPlugin
         https: false, // 是否使用https
         noInfo: true, // 在热更新时,只会输出错误与警告信息,不会输出其他日志
         stats: "verbose" // 输出所有日志
     },    

     // 配置插件(未完待续)
     plugins: [
         new webpack.EnvironmentPlugin([‘NODE_ENV‘]),  // 可以随意指定前端node环境
         new webpack.DefinePlugin({
           ‘process.env‘: {NODE_ENV: JSON.stringify(process.env.NODE_ENV)}   // 可以随意指定前端node环境
         }),
         new extractTextPlugin("css/[name].css"),       // css抽取,需要引入模块extract-text-webpack-plugin,并且需要在模块加载器处也加入对应配置
         new HtmlWebpackPlugin({                        // html插件,定义html模板,生成html文件,并将指定的模块插入html中(需要引入模块html-webpack-plugin)
             template: path.join(‘src/‘, ‘template.html‘),  // 模板html文件的存放位置
             filename: path.join(‘build/‘, ‘index.html‘),   // 指输出的每个html文件名称及存放路径的定义
             inject: ‘body‘,                                // 表示插入至body标签内
             chunks: [      // 插入的模块在html上会自动使用publicPath与模块的filename作为引用路径
                index       // 插入index入口模块,也可以插入其他入口模块或者公共模块(比如使用CommonsChunkPlugin提取的common模块)
             ],
         }),
         // 提供公共代码
         new webpack.optimize.CommonsChunkPlugin(‘common.js‘), // 默认会把所有入口节点的公共代码提取出来,生成一个common.js
         new webpack.optimize.CommonsChunkPlugin(‘common.js‘,[‘main‘,‘index‘]), // 默认会把所有入口节点的公共代码提取出来,生成一个common.js, 只提取main节点和index节点
         new webpack.optimize.CommonsChunkPlugin({          // 有选择性的提取(对象方式传参)
             name: "common",                                // name可以是做生意模块名(common是公共模块名)注意不要.js后缀
             filename: "js/[name].js",                      // 指定输出的js文件名称及路径
             chunks: [‘main‘,‘user‘,‘index‘],               // 将指定的入口模块提取出来
             minChunks: 2                                   // 公共模块被使用的最小次数。比如配置为2,也就是同一个模块只有被2个以外的页面同时引用时才会被提取出来作为common chunks。
         }),
         new webpack.optimize.CommonsChunkPlugin({          // 有选择性的提取(对象方式传参)
              name: "index",                                // name可以是任意模块名,注意不要.js后缀
              filename: "js/[name].js",                     // 指定输出的js文件名称及路径
          }),
         new webpack.HotModuleReplacementPlugin(),  // 热更新插件,使用dev-server必备
         new webpack.NoEmitOnErrorsPlugin(),        // 在webpack 2中使用NoErrorsPlugin会有警告提示
         new webpack.ProgressPlugin(function(percentage, msg) {
             logUpdate(percentage * 100 + ‘%‘, msg);  // 实时更新编译进度,需要同时使用实时更新日志模块log-update
         }),
         new webpack.optimize.UglifyJsPlugin({        // 解析/压缩/美化所有的js模块,如有需要,这里可以通过配置except可以防止变量被改变
             mangle: {
                 except: [‘$super‘, ‘$‘, ‘exports‘, ‘require‘]
             }
         }),

         // 自定义插件函数,函数会接受到webpack的编译对象compiler,用this同样也能获取到
         function(compiler) {
             this.plugin("done", function(stats) {  //使用.plugin api增加自定义插件,‘done‘表示触发时机为编译结束后,stats表示编译生成的模块的详细信息
                 require("fs").writeFileSync(path.join(__dirname, "stats.generated.json"), JSON.stringify(stats.toJson()));
                 require("open")((‘http://localhost:9090/index.html‘)); // 还可以在编译完成后控制自动唤起浏览器并打开项目的入口页面(需要安装open模块)
             });
         },
     ],
};

module.exports = webpackConfig;

  

webpack 启动 devServer

var webpackConfig = require(‘./webpack.config‘);  // 获取webpack配置
var webpack = require(‘webpack‘);
var WebpackDevServer = require(‘webpack-dev-server‘);
var devServerOptions = {
    // 配置代理服务器
     proxy: {
       ‘/api‘: ‘http://localhost:3000‘ // 访问路由/api,会转发到localhost:3000的地址去
     },
     contentBase: [ path.resolve(__dirname, "build"), path.resolve(__dirname, "mock") ], //  静态资源路径,需要配置编译后的模块文件存放的路径(同output中的path),也可以在这里配置其他的,比如mock文件存放的路径
     compress: true, // 是否开启压缩
     historyApiFallback: true, // true for index.html upon 404, object for multiple paths
     hot: true, // 是否开启热更新,需要配置HotModuleReplacementPlugin
     https: false, // 是否使用https
     noInfo: true, // 在热更新时,只会输出错误与警告信息,不会输出其他日志
     stats: "verbose" // 输出所有日志
};

var compiler = webpack(webpackConfig);
var webpackDevServer = new WebpackDevServer(compiler, devServerOptions);
webpackDevServer.listen(‘9090‘, ‘http://localhost‘, function (err) {
    if (err) {
        console.error(err);
    }
});

  

时间: 2024-10-16 10:40:28

webpack使用小记的相关文章

webpack 小记

零.入口与输出 //对像语法 entry: { aa: __dirname + '/src/aa.js',    //(chunkName :path) bb: __dirname + '/src/bb.js' }, output: { filename: '[name]-[hash].js', path: __dirname + '/dist' } //单入口 entry: './src/aa.js', output: {  filename: 'bundle.js',            

关于webpack下热更新?&amp;自动刷新?的小记(非vue-cli)

写本随笔时:webpack4.6.0 为何标题用?号,因为老衲也不知是否用词正确,大概是这样的说法: webpack4.0引入生产模式和开发模式,在开发时使用 webpack 打包后不压缩,所以只需要在 webpack 打包命令中加上 --mode mode development 即可. 如果没有 mode development 就会自动使用 production 模式,所有打包的代码将会是压缩过的,没办法调试 实践: index.html引入的bundle.js文件,必需是webpack-

Vue.js系列之项目搭建(vue2.0 + vue-cli + webpack )

1.安装node node.js环境(npm包管理器) cnpm npm的淘宝镜像 从node.js官网下载并安装node,安装过程很简单,一路"下一步"就可以了(傻瓜式安装).安装完成之后,打开命令行工具,输入 node -v,如果出现相应的版本号,则说明安装成功. npm包管理器,是集成在node中的,所以,直接输入 npm -v就会显示出npm的版本信息. 2.安装cnpm 在命令行中输入 npm install -g cnpm --registry=http://registr

angular踩坑之路:初探webpack

之前费了一番力气安装好了angular开发环境,后面的几天都是在angular中文官网上看文档,照着英雄教程一步一步操作,熟悉了angular的一些基本特性,这部分没有遇到什么大问题,还比较顺利.这两天在看官方文档中的Webpack简介,想跟着文档做一遍,了解一下如何用Webpack打包angular项目,结果遇到了一些问题,因为是初学angular和Webpack的小白,这些问题一时难以解决,花费了不少时间,想在这里记录一下. 首先跟着文档将相关的文件都添加到项目中,目录是这样子的: 根据文档

WebPack+WebStorm调试

怎么用webstorm来调试WebPack? 今天查了很多文档,最终在官网上耐心看完英文文档后,才解决.附上链接:https://blog.jetbrains.com/webstorm/2015/09/debugging-webpack-applications-in-webstorm/ 工具简介 Windows7 WebStorm2017 Webpack2 谷歌浏览器(默认浏览器) 操作 在Project视图里找到index.html,右击进入Debug模式 WebStrom会自动进入Debu

SpringBoot - 二零一七0421小记

一.SpringBoot使用起来比起SpringMVC更便捷,在注解上的小变化,我记录了下面几个: @Controller + @ResponseBody = SpringMVC中用@RestController来代替前面两个注解,通过这个注解,可以将所有的前端http请求放入SpringBoot的Controller容器中,并返回json格式的数据给前端 @RequestMapping(value={"/hello","/hi"},method=RequestMe

webpack教程

1 安装 webpack 2 初始化项目 3 webpack 配置 4 实时刷新 5 第三方库 6 模块化 7 打包.构建 安装 webpack# 我们通过 npm 在全局环境下安装 webpack: npm install webpack -g 安装完成后,我们可以使用 webpack 命令,执行 webpack --help 能够查看 webpack 提供的所有命令. 不过,建议在项目下安装一份局域的 webpack: npm install webpack --save-dev 如果觉得

webpack

30分钟手把手教你学webpack实战 阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解babel-loader加载器的含义 六:了解下webpack的几个命令 七:webpack对多个模块依赖进行打包 八:如何独立打包成样式文件 九:如何打包成多个资源文件 十:关于对图片的打包 十一:React开发神器:react-hot-loader 回到顶部 什么是webpack? 他有什么优点?

Vue2.0与 [百度地图] 结合使用———vue+webpack+axios+百度地图实现组件之间的通信

Vue2.0与 [百度地图] 结合使用: 1.vue init webpack-simple vue-baidu-map 2.下载axios cnpm install axios; 3.在main.js中引入axios,并使用 import axios from 'axios' /* 把axios对象挂到Vue实例上面,其他组件在使用axios的时候直接 this.$http就可以了 */ Vue.prototype.$http = axios; 4.引入百度地图的js秘钥--->最好在inde