对于配置过程本文就不一一赘述了,只是简单就一些配置可能遇到的问题做个总结
先看webpack.config.js基本配置
入口和出口
entry:{ index:__dirname + "/src/main.js",//唯一入口 }, output:{ path:path.resolve(__dirname+"/dist"), filename:"[name]-[hash].js" },
入口和出口,单页应用唯一的入口文件,这个没什么好说的
需要注意的是如果用的是2x以上版本的webpack,如果output的filename直接写bundle.js压缩防止重复时会报错
接下来是常用的loader
module: {//loader定义的地方,使用前需要npm 安装 rules: [ { test:/(\.html)$/, use:{ loader:"html-loader", }, },{//处理es6语法,和jsx语法 test:/(\.jsx|\.js)$/, use:{ loader:"babel-loader", }, exclude:/node_modules/ },{ test: /\.(png|gif|jpe?g)$/, loader: 'url-loader', query: { /* * limit=10000 : 10kb * 图片大小小于10kb 采用内联的形式,否则输出图片 * */ limit: 10000, name: '/img/[name]-[hash:8].[ext]' } },{ test: /\.css$/, use: extractCSS.extract({ fallback:"style-loader", use:[ 'css-loader'] }) }, { test: /\.less$/i, use: extractLESS.extract({ fallback:"style-loader", use:[ 'css-loader', 'less-loader'] }) }, ] }
配置module需要注意一下几点:
一、file-loader和url-loader
url-loader封装了file-loader。url-loader不依赖于file-loader,即使用url-loader时,只需要安装url-loader即可,不需要安装file-loader,因为url-loader内置了file-loader。通过上面的介绍,我们可以看到,url-loader工作分两种情况:1.文件大小小于limit参数,url-loader将会把文件转为DataURL;2.文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。因此我们只需要安装url-loader即可。
二、处理es6,es7语法 babel
除了安装babel-core babel-loader 还要安装转码es对应的babel-preset-esXX。
之前看到很多博客提到babel-preset-env处理一切版本的es不需要再麻烦的去安装每个版本。尝试了几次,开发没有问题,es6,es7的语法都可以正常解析为es5。但是再压缩js的时候始终报错。
表面上看是报的静态资源的问题,通过断点测试,其实是es6语法不支持,于是我安装了babel-preset-es2015,配置了.babelrc文件
//.babelrc { "presets": ["react", "es2015"] }
问题得到了解决
代码从1.9M压缩到了几百K
三、抽离从js中抽离css,html等静态资源
上述代码中的extractCESS,extractLESS是extract-text-webpack-plugin插件实例化的对象
使用时首先要npm install 安装改插件。使用时除了再module中配置意外还需要再plugin中声明
//webpack.config.js plugins:[ extractCSS, extractLESS ]
常用的插件plugin
plugins:[ /* *create html file * (创建html文件) * */ new HtmlWebpackPlugin({ template:__dirname+"/src/index.tmpl.html" }), new HtmlWebpackPlugin({ filename: 'html/tmpl.html', template: __dirname + '/src/tmpl.html', inject: false, }), /* * Module (value) is loaded when the identifier (key) is used as free variable in a module * (如:使用jquery 可以直接使用符号 "$") * */ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery", "_": "underscore" }), /* *热加载插件,如果配合react使用, *需要安装babel-plugin-react-transform react-transform-hmr配合babel * */ new webpack.HotModuleReplacementPlugin(), /* *清除打包文件夹中多余的js文件 * */ new cleanWebpackPlugin(['dist']), extractCSS, extractLESS, /* * CommonsChunkPlugin(防止重复) * */ new webpack.optimize.CommonsChunkPlugin({ name:'common'//指定公共的bundle的名称 }) ],
都是一些常用的插件没有太多需要解释的,不过上面配置ProvidePlugin时,直接使用“jquery”是因为我再resolve中对资源进行了重命名
解析resolve
resolve: { /* * An array of extensions that should be used to resolve modules * (引用时可以忽略后缀) * */ extensions: ['.js', '.css', '.scss','.less','.ejs', '.png', '.jpg','.html'], alias: { /* * js */ jquery: path.join(path.resolve(process.cwd(), './libs'), "js/jquery"), /* * css,bootstrapcss重命名,需要引用的地方,可以直接require别名无需写路径,非常方便 */ bootstrapcss: path.join(path.resolve(process.cwd(), './libs'), "bootstrap/bootstrap-3.3.5.css"), } }
简单说明一下:path.resolve和process.cwd()都是nodejs的方法
path.resolve()
方法会把一个路径或路径片段的序列解析为一个绝对路径。
给定的路径的序列是从右往左被处理的,后面每个 path
被依次解析,直到构造完成一个绝对路径。 例如,给定的路径片段的序列为:/foo
、/bar
、baz
,则调用 path.resolve('/foo', '/bar', 'baz')
会返回 /bar/baz
。
process cwd()
方法返回 Node.js 进程当前工作的目录。
所以path.resolve(process.cwd(), './libs')翻译成人话就是:当前项目下的libs文件夹下
最后说明一下环境的构建:
开发模式下配置一个可以热更新和自动打开浏览的服务器
//webpack.dev.js const merge = require('webpack-merge'); const common = require('./webpack.config.js'); module.exports = merge(common, { devtool: 'inline-source-map', devServer: { contentBase:"./dist",//本地服务器所加载的页面所在的目录 historyApiFallback:true,//不跳转 inline:true,//实时刷新 hot:true,//热加载 open:true//自动打开浏览器 } });
生产模式下需要压缩代码
//webpack.prod.js const webpack = require("webpack") const merge = require('webpack-merge'); const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); const common = require('./webpack.config.js'); module.exports = merge(common, { devtool:"source-map", plugins: [ new UglifyJSPlugin({ sourceMap:true }), new webpack.DefinePlugin({ /* *许多 library 将通过与 process.env.NODE_ENV 环境变量关联,以决定 library 中应该引用哪些内容。 */ "process.env":{ 'NODE_ENV':JSON.stringify('production') } }) ] });
ps:技术上讲,NODE_ENV
是一个由 Node.js 暴露给执行脚本的系统环境变量。通常用于决定在开发环境与生产环境(dev-vs-prod)下,服务器工具、构建脚本和客户端 library 的行为。然而,与预期不同的是,无法在构建脚本 webpack.config.js
中,将 process.env.NODE_ENV
设置为 "production"
,请查看 #2537。因此,例如 process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js'
这样的条件语句,在 webpack 配置文件中,无法按照预期运行。
//package.json "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack", "dev": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js" },
在node命令行中运行npm run dev 就会开启开发模式
运行,npm run build 项目会被打包到dist目录下,上线时只需要上传dist目录下的文件即可
总结,这个配置在性能优化方面可能还是不足,不过,基本已经实现了打包,分离开发模式与生产模式。源码也都穿上来了,与兴趣的可以下载参考。
本文为唯雪原创文章,转载无需和我联系,但请注明来自唯雪博客cocostory.cn
越过死海:
2018-01-11 10:12:29 回复