webpack

185 阅读5分钟
第一步: 在packjson.js中加入build  "build": "webpack --mode development",
第二步: 写一个webpack配置文件---> webpack.config.js
    // webpack内部有一个事件流,tapable
    webpack启动后会从Entry里配置的Module开始递归解析Entry依赖的所有的Module。没找到一个Module,
就会根据配置的Loader去找出对应的转换规则,对Module进行转换后,再解析出当前的Module依赖的Module。
这些模块会以Entry为单位进行分组,一个Entry和其所有依赖的Module被分到一个组也就是一个chunk,
最后Webpack会把所有的Chunk转换成文件输出。在整个流程中webpack会在恰当的时机执行plugins里面的逻辑
loader的作用:
    在require的时候,其实就是把require的文件作为一个模块,回去module里面看模块处理规则
打包完成的bundle.js怎么插入index.html呢?
    最开始:通过file协议手动打开一个静态文件
    高级:通过一个服务 webpack-dev-server,
        在package.json中有一个配置 "webpack-dev-server --open --mode development"
        --open  在打包完成后就自己打开浏览器,而不需要我们去打开
        npm run build 和 npm run dev还是有区别?
都会打包,但是npm run dev打包后生成的build文件其实是在内存中的,但是
npm run build生成的文件是由output决定位置的
webpack怎么打包一个多页应用?
    本质是产生多个html页面,引入各自的js,那么怎么做呢,记住多个new HtmlWebpackPlugin,那么怎么做到在index.html引入index.js
    在base.html里面引入base.js呢?不要忘记了有个 HtmlWebpackPlugin 有个chunks,chunks: ['index'], //在产出的代码块中引入哪些代码块
    这样就解决了引入对应的js文件,那么chunks数组里面的元素怎么拿到的呢: 其实取的是entry对象的属性,因为是唯一的
那么就如上面那个问题?base.js  和   index.js 都引入了jquery,
    怎么引入jquery,最笨的方法:用到jquery的页面里面都import $ from 'jquery' 能让一个js文件里面使用$("#app").html('hello')
    但是你打包完看下你的index.js和base.js,size都300多k了,太大了,
那么怎么解决上面那个js太大的问题呢?
    引入一个新的入口vendor,专门用来存放第三方库,也就是打包过后会多了一个模块,叫vendor,然后index.html和base.html要使用第三方模块,
    那么就在自己的html-webpack-plugins里面的chunks属性添加这个vendor模块,这样做的好处是index在引用jquery的时候把他缓存了,
    在base.js引用的时候直接读取缓存里面的东西,那么就提升了速度
但是你又会遇到一个问题:
    在index.html页面里面使用jquery的时候,npm run dev会报没有定义$,也就是第三方库的变量$没有插入,
那怎么插入变量呢?
    请您使用这个插件:new webpack.ProvidePlugin({$ : 'jquery'})
再问一个问题: a.js 中引入了jquery,a中也引入了b.js,那么能在b.js中用jquery吗,肯定是不能的,因为闭包,单独的作用域,那么问题来了,
我想让$变为全局变量:在index.js   let $ = require('expose-loader?$!jquery'); 
上面那个和require('style-loader!css-loader!./index.css')是一样的,从右到左,用!分隔开,遇到文件就加载,遇到loader就转换,遇到?就是传参数
// expose-loader?全局变量名: 模块名 先加载模块  把模块的导出对象挂载在window上  使用方法: window.$
laoder的两种写法: 一种是写在rule里面,另外一种写在require里面的
rules: [
           {
               test: /^jquery$/,
               loader: 'expose-loader?$'
           }
]
1.怎么使用图片?
    File-loader是解析图片地址,把图片从源位置拷贝到目标位置并且修改原引用地址
    可以处理任意的二进制数据,比如UI框架的字体数据
    a.在js文件引入图片,file-loader 和 url-loader
    b.样式中引用图片: 路径的写法 css-loader 和 style-loader
    c.在页面中使用图片: html-withimg-loader
     html中直接使用img标签src加载图片的话,因为没有被依赖,图片将不会被打包。这个loader解决这个问题,
     图片会被打包,而且路径也处理妥当。额外提供html的include子页面功能。
d.图片打包后放在一个固定的文件夹怎么做?
e.图片很小的时候把图片变成base64字符串内嵌到页面中:
少一次资源请求
2.怎么处理less和sass?(sass-loader要用cnpm 下载)
打包的时候自动添加前缀,postcss-loader,记着在postcss.config.js里面配置下就好了
3.怎么提取公用的css文件? extract-text-webpack-plugin
    npm install --save-dev extract-text-webpack-plugin@next 否则4.0以上不支持
    优点:像公用的css文件只需加载一次就可以缓存了,比如bootstrap下的css文件
4.css怎么自动加前缀? 要使用postcss-loader预处理,打包的时候看css文件中哪些css属性需要添加前缀,需要添加一个
postcss.config.js配置文件
5.es6怎么编译?
cnpm i babel-preset-env 替换了 babel-preset-es2015
cnpm i babel-core babel-loader babel-preset-es2015 babel-preset-react 
babel-preset-stage-0 -D
{
    test: /\.js/,
    // babel-loader没什么用,主要起作用的是env:es6    stage-0:es7   
    use: {
        loader: 'babel-loader',
        query: {
            presets: ['env', 'stage-0', 'react']
        }
    }
}
6. devtool设置,定位错误,和打包速度有关,这个看下文档就可以了
7.怎么监控源文件的变化:watch属性  
8.拷贝的插件: copy-webpack-plugin
9.压缩css怎么做: 加一个?minimize被移除了
10.怎么压缩js 
 webpack.optimize.UglifyJsPlugin  自带的插件或者下面的这个第三方插件
 const UglifyjsWebpackPlugin= require('uglifyjs-webpack-plugin')
11.别名:resolve
12.看webpack源码记得装一个插件: vscode-webpack-debugge