ps:npm init 的方式初始化项目而不是采用脚手架的方式
- npm init
- cnpm i webacpk vue vue-loader //vue需要依赖vue-loader
- cnpm i css-loader vue-template-compiler
文件夹如下:
app.vue代码
- <template>
- <div id="app">
- 123
- </div>
- </template>
-
- <script>
-
- </script>
-
- <style scoped>
- #app {
- color:red
- }
-
- </style>
index.js代码
- import Vue from 'vue' // app.vue依赖vue源码
- import App from './app.vue'
-
-
- const root = document.createElement('div')
- document.body.appendChild(root); // root 节点需要创建
-
- new Vue({
- render: (h) => h(App) // h 是vue中的createApp
- }).$mount(root) //$mount把我们的app 挂载到我们的html的root节点下
webpack.config.js代码
- const path = require('path')
- const config = {
- entry: path.join(__dirname, 'src/index.js'), //入口 拼接绝对路劲 + src
- output: {
- filename: 'bundle.[hash:8].js', // 开发环境和正式环境输出的filename是不同的
- path: path.join(__dirname, 'dist')
- },
- module: {
- rules: [
- {
- test: /\.vue$/, // .需要通过\转义
- loader: 'vue-loader' // 自动加载模块功能
- }
- ]
- },
- }
webpack.config.js代码
- {
- "name": "create_196",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1",
- "注释": "不在这里声明,就会调用全局的webpack",
- "build": "webpack --config webpack.config.js",
- "注释": "dev 是开发环境",
- "dev1": "webpack-dev-server --config webpack.config.js",
- },
-
- }
ps:若遇到以下这样报错,需要配置loader,因为webpack默认只能解析js文件,vue文件webpack不能解析需要配置loader
webpack能加载我们前端项目用的所有资源。各种静态资源,图片,css,css预处理(tets.styl)等
安装的所有依赖及版本放置文章最后面,放在文章最后面,可以先安装
- module: {
- rules: [
- {
- test: /\.vue$/, // .需要通过\转义
- loader: 'vue-loader' // 自动加载模块功能
- },
- {
- test: /\.jsx$/,
- loader: 'babel-loader'
- },
- { // .css文件
- test: /\.css$/, // .需要通过\转义
- // loader: 'css-loader' // 只是处理了css文件
- use: [
- 'style-loader', // 写入到html中,插入到html中<style link='test.css'></style>
- 'css-loader', // 只是读取了css文件
- ]
- },
- {
- // test: /\.styl$/, // 这样配置会有个错误Module parse failed: Unexpected character '#',使用下面配置处理
- test: /.styl(us)?$/,
- use: [
- 'style-loader',
- 'css-loader',
- 'stylus-loader' //先执行stylus-loader解析后为css 然后再通过css-loader读取css webpack的loader 就是一层一层的往上传递
- ]
- },
-
- {
- test: /\.(gif|jpg|jpeg|png|svg)$/, //
- use: [
- { //这里为何要有{},因为每个loader都可以配置的 options:{}
- loader: 'url-loader', // 直接以base64的格式写入js中,减少http请求,依赖于file-loader
- options: { // url-loader配置
- limit: 1024,
- name: '[name]-aaa.[ext]' //ext扩展名,输出的图片名字
- }
- }
- ]
- },
- ]
- },
webpack-dev-server及热更新:
- //方便调试,因为通过webpack编译后都是编译后的代码不利于调试,故需配置devtool,在浏览器中就是我们写的代码,source-map模式有很多(行定位准确)
- config.devtool = '#cheap-module-eval-source-map'
- // devServer会启动一个服务,服务会监听一个端口
- config.devServer = {
- port: 8000,
- host: '0.0.0.0', // 不设置成loachost的好处 0.0.0.0可以通过localhost:8080/访问,127.0.0.1也能访问 ,通过电脑ip访问在别人电脑访问及手机,设置成localhost他人电脑无法访问
- overlay: {
- errors: true // 编译过程中报错信息 会输出在网页中,我们可以快速改掉报错的地方
- },
- // open: true, //自动打开浏览器。每次修改都会重新打开页面
- // historyFallback: { }//开发的是单应用 定义路由将很多webpack不认识的地址映射到index.html入口上
- hot: true //只更新修改组件页面,不用重新刷新浏览器
- }
- config.plugins.push( // 热更新所需配置
- new webpack.HotModuleReplacementPlugin(), // hot热加载需要的插件
- new webpack.NoEmitOnErrorsPlugin() //可以减少错误信息的展示
- )
cross-env:是一套命令能在mac和windows上使用,mac和windows设置环境变量语法不同 ,通过NODE_ENV2=123 ,都存在process.env这个对象里面
- "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
- "dev": "cross-env NODE_ENV=development NODE_ENV2=123 webpack-dev-server --config webpack.config.js"
html-webpack-plugin: 是提供一个入口类似index.html,自动把所需的js及图片资源引入到html中
- const HTMLPlugin = require('html-webpack-plugin'); //dev-server需要的
-
- plugins: [
- //new webpack.DefinePlugin是 vue react使用这些框架开发必加的一个plugin
- // 作用是 1.webpack在编译的过程中以及在我们自己在js中判断环境 都可以调用NODE_ENV这个变量
- // 2.这些框架打包时会通过不同的环境会去区分打包 很多不同版本的vue源代码,开发环境中时比较大体积的版本
- // 因为里面内置了很多错误信息提示,我们在生产环境是不需要的会加大代码体积以及降低运行效率
- new webpack.DefinePlugin({ // 这个插件在webpacK上需引入webpacK
- 'process.env': {
- NODE_ENV: 'isDev' ? '"development"' : '"production"'
- }
- }),
- new VueLoaderPlugin(),
- // 一个html容纳bundle.js
- new HTMLPlugin()
- ]
ps:若遇到以下这样报错,1.删除 node_modules 目录 2.npm cache clean --force (清除掉cache缓存) 3.npm install
postcss.config.js配置如下:
- const autoprefixer = require('autoprefixer')
-
- // 后处理,我们的css代码通过style-loader css-loader 处理后需要css代码优化 如自动加前缀-webkit等
- module.exports = {
- pluginss: [
- autoprefixer()
- ]
- }
.babelrc
-
- {
- "presets": [
- "env"
- ],
- "plugins": [
- "transform-vue-jsx"
- ]
- }
footer.jsx
- export default {
- data() {
- return {
- author: "cookie",
- list: [1, 2],
- };
- },
- render() {
- return (
- <div id="footer">
- <span>jsx 语法 {this.author}</span>
- </div>
- );
- },
- };
打包出来的bundle.js还包含了css文件,明显不有利于我们做浏览器缓存,需要抽离css文件,打包成单独的文件
- // 单独分离css
- const ExtractPlugin = require('extract-text-webpack-plugin')
-
-
- config.module.rules.push({
- // test: /\.styl$/, // 这样配置会有个错误Module parse failed: Unexpected character '#',使用下面配置处理
- test: /.styl(us)?$/,
- use: ExtractPlugin.extract({
- fallback: 'style-loader', // 把css-loader的代码包一层js代码,这个一层js代码是写入到我们html当中的
- use: [
- 'css-loader',
- {
- loader: 'postcss-loader', // 添加postcss.config.js , webkit前缀
- options: {
- souerMap: true, // 可直接使用前面的souerMap,提高编译效率
- }
- },
- 'stylus-loader' //stylus-loader解析后是css webpack的loader 就是一层一层的往上传递
- ]
- })
- })
- config.plugins.push(
- new ExtractPlugin('styles.[contentHash:8].css'), // 指定输入的文件名,根据css内容输出的name值
- )
ps:为什么要把第三方类库和业务逻辑代码分离打包?
如果把业务逻辑代码和第三类库打包到一起,整个类库代码就需要随着业务代码的更新而更新,这样类库代码就不能在浏览器里进行缓存。为了尽可能的使用浏览器缓存来减少服务器流量,以及用户加载速度更快,所以单独拆分出来进行打包
ps:为什么要把webpack配置单独抽离?
webpack配置单独打包在一个文件中,在有新的模块加入时,webpack会给每个模块加个id上去,会导致hash发生变化,这样我们的浏览器缓存就失效了,webpack配置单独打包成一个文件 好处是预防这种问题发生,保证浏览器长缓存
- config.entry = {
- entry: path.join(__dirname, 'src/index.js'),
- // vendor: ['vue', 'vue-router', 'vuex'] // 定义需打包类库的name
- vendor: ['vue']
- }
-
-
- config.plugins.push(
- new webpack.optimize.CommonsChunkPlugin({
- 'name': 'vendor' // vendor必须与上面定义的字段相同,注意点vendor一定要放在runtime前面
- }),
- new webpack.optimize.CommonsChunkPlugin({
- 'name': 'runtime' //注意顺序一定要写在后面 把在dist/entry.js 里面的webpack配置单独打包在一个文件中,在有新的模块加入时,webpack会给每个模块加个id上去,会导致hash发生变化,这样我们的浏览器缓存就失效了,webpack配置单独打包成一个文件 好处是预防这种问题发生,保证浏览器长缓存
- }),
- )
如果我们声明chunk (vendor:['vue“])还使用hash那就没什么意义了,因为我们每次打包业务代码的时候 我们的类库也会跟着改变,就做不到浏览器缓存
使用chunkhash与hash的区别,chunkhash就是声明不同节点entry的chunkhash,hash是整个应用的hash,很明显我们只有一个应用(都使用hash会导致hash值一样)
源码链接:https://gitee.com/zhangcookie/wbpack3_vue_todo-list.git