搜尋
首頁web前端js教程建置vue2 vue-router2 webpack3 工程教學

本文主要介紹了詳解從零搭建 vue2 vue-router2 webpack3 工程,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧。希望能幫助大家。

以新手視角,詳細介紹各個步驟內容,不深入講步驟涉及的原理,主要介紹如何操作。

初始化工程

新工程目錄vue2practice,在目錄下執行npm init -y來建立一個package.json,在package.json 中先加入以下必備模組:

{

 "name": "vue2-vue-router2-webpack3",

 "version": "1.0.0",

 "devDependencies": {

  "vue": "^2.4.2",

  "vue-loader": "^13.0.2",

  "vue-router": "^2.7.0",

  "vue-template-compiler": "^2.4.2",

  "webpack": "^3.4.1",

  "webpack-dev-server": "^2.6.1"

 }

}

其中vue-template-compiler 是vue-loader 的peerDependencies,npm3 不會自動安裝peerDependencies,然而vue-template-compiler 又是必備的,那為什麼作者不將其放到dependencies 中呢?有人在 github 上提過這個問題,我大致翻譯一下作者的回答(僅供參考):這樣做的原因是因為沒有可靠的方式來固定嵌套依賴的關係,怎麼理解這句話?首先vue-template-compiler 和vue 的版本號碼是一致的(目前是同步更新),將vue-template-compiler 指定為vue-loader 的dependencies 並不能保證vue-template-compiler 和vue 的版本號碼是相同的,讓使用者自己指定版本才能保證這一點。查看作者的回答(英文) 。如果兩者版本不一致,運行時會出現下圖所示的錯誤提示。

新目錄結構如下,新增的目錄及檔案先空著,後面的步驟會說明新增什麼內容。

vue2pratice

  |-- package.json

  |-- index.html     // 启动页面

  |-- webpack.config.js // webpack配置文件

  |-- src

    |-- views    // vue页面组件目录

    |-- main.js   // 入口文件

    |-- router.js  // vue-router配置

    |-- app.vue   // 工程首页组件

設定Webpack

Webpack 預設讀取 webpack.config.js,檔案名稱不能隨便改,其中 entry 是必須設定的。

module.exports = {

  entry: './src/main.js',

  output: {

    path: __dirname + '/dist',

    publicPath: '/static/',

    filename: 'build.js'

  }

}

Webpack 2+ 要求output.path必須為絕對路徑。

設定 webpack-dev-server,只需在 package.json 新增以下啟動指令即可。

"scripts": {

 "dev": "webpack-dev-server --hot --open"

}

webpack-dev-server 2 預設為 inline 模式,熱模組替換仍需自行設定。

驗證設定

在 index.html 中新增測試程式碼,引入打包後的 JS 檔案。


  Hello, Webpack 3.

  <br>

  <script></script>

在 main.js 中加入測試程式碼。

// main.js

document.write('来自main.js的问候!')

執行下面的命令來安裝模組並啟動伺服器。

// 安装依赖

npm install

 

// 运行

npm run dev

啟動後瀏覽器會自動開啟http://localhost:8080,如果主機沒有報錯,頁面正確顯示main.js 和index.html 的內容,改動main.js 後瀏覽器不刷新能看到效果,則表示配置沒問題。

Vue

新頁面

#在 views 目錄下新 index.vue。

<template>

  <p>

    这是{{page}}页面

  </p>

</template>

<script>

export default {

  data: function () {

    return {

      page: &#39;index&#39;

    }

  }

}

</script>

webpack 1 需要特定的 loader 來轉換 ES 2015 import/export,webpack 2 起可以開箱即用。但是 ES6 的新語法還是需要 loader 來轉換,在沒有設定前,先不要用新語法。用了也沒報錯(例如 let,const等),那是因為你的瀏覽器已經支援了 ES6 語法(新版本瀏覽器都已經支援)。

設定路由

將 vue-router 實例化傳入的參數new VueRouter(參數)提取到 router.js 形成路由設定檔。

import index from './views/index.vue'

export default {

  routes: [

    {

      path: '/index',

      component: index

    }

  ]

}

從 vue-loader@13.0.0,不能用 require 來引入 .vue 文件,因為 .vue 檔案最終會被編譯成 ES6 module。

首頁

首頁引入 ouput 設定的 JS,新增 Vue 實例的掛載目標。


<p></p>

<script></script>

入口JS完成路由設定、初始化 Vue 實例。

import Vue from 'vue';

import VueRouter from 'vue-router';

import App from './app.vue';

import routerConfig from './router';

Vue.use(VueRouter);

var router = new VueRouter(routerConfig)

new Vue({

  el: '#app',

  router: router,

  render: h => h(App)

});

從Vue 2.2.0 後使用require('vue') 會報錯,應使用ES6 module(import),具體原因請參考Vue 更新說明https://github.com/vuejs/vue/ releases,截圖如下:

在首頁元件app.vue 中新增路由連結、路由視圖元件。

<template>

  <p>

    </p>
<p>

      <router-link>Home</router-link>

    </p>

    <p>

      <router-view></router-view>

    </p>

  

</template>

設定loader

設定 vue 檔案對應的 loader。

module: {

  rules: [

    {

      test: /\.vue$/,

      use: ["vue-loader"]

    }

  ]

}

Webpack2 必須在 module.rules 下設定 loader。 '-loader'不能省略,必須將 loader 名寫全。可以使用 Rule.use 或 Rule.loader 來設定 loader(Rule.loader 是 Rule.use: [ { loader } ] 的簡寫),建議使用 use。

上面完成了新增頁面及存取該頁面所需的配置,以下來測試下是否能正常存取/index。執行npm run dev,瀏覽器顯示如圖介面。

支援CSS

安裝css-loader 後即可在vue 檔案中使用

npm i css-loader -D

想要支援import / require引入CSS文件,則需要配置對應的Rule。

{

  test: /\.css$/,

  use: ["vue-style-loader", "css-loader"]

}
<script>

import "../style/style.css"

</script>

支援CSS預處理語言

以 stylus 為例,安裝 stylus 及 stylus-loader。

npm install stylus stylus-loader -D

增加 .styl 檔案對應的 loader 設定。

{

  test: /\.styl$/,

  use: ["vue-style-loader", "css-loader", "stylus-loader"]

}

使用範例:

<style>

  .stylus

    .red

      color red

</style>

<script>

  import "../css/stylus-example.styl"

</script>

node-sass 安裝慢的解決方案

使用淘寶鏡像:

npm set disturl https://npm.taobao.org/dist

也可以單獨設定node-sass鏡像:

npm set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass

支援圖片及圖示字體

安装图片及图标字体依赖的loader。

npm install url-loader file-loader -D

增加图片及图标字体的loader配置。

{

  test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,

  use: [{

    loader: "url-loader",

    options: {

      limit: 10000,

      name: 'images/[name].[hash:7].[ext]'  // 将图片都放入images文件夹下,[hash:7]防缓存

    }

  }]

},

{

  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,

  use: [{

    loader: "url-loader",

    options: {

      limit: 10000,

      name: 'fonts/[name].[hash:7].[ext]'  // 将字体放入fonts文件夹下

    }

  }]

}

构建

添加打包命令如下:

"build":"webpack --progress --colors"

执行npm run build开始构建,完成后,可以看到工程目录下多了dist目录以及 dist/build.js。 

使用 Webpack 插件

压缩JS

在之前的文章提到过,打开未压缩版的build.js,你会发现ES6的语法没有被转化为ES5,因此需要安装babel 套件来完成语法的转化,否则压缩的时候就会报错。之前广泛使用的转码规则为 babel-preset-es2015,但 Babel 的官网上在9月宣布 ES2015 / ES2016/ ES2017 等等 ES20xx 时代的 presets 通通被废弃(deprecated),取而代之的是 babel-preset-env,并且承诺它将成为“未来不会过时的(future-proof)”解决方案。

npm i babel-loader babel-core babel-preset-env -D

增加babel的配置文件.babelrc。

{

  "presets": [

    ["env", { "modules": false }]

  ],

  "comments": false

}

将 modules 设置为 false,即交由 Webpack 来处理模块化,通过其 TreeShaking 特性将有效减少打包出来的 JS 文件大小,可以自行对比下前后打包出来的文件的大小,效果还是不错的。

comments 即是否保留注释。

接着配置 JS 文件的 loader。

{

  test: /\.js$/,

  use: "babel-loader",

  include: [path.resolve(__dirname, 'src')]

}

注意:Webpack2建议尽量避免exclude,更倾向于使用include。

压缩 JS 采用webpack.optimize.UglifyJsPlugin,配置如下:

new webpack.optimize.UglifyJsPlugin()

官网称warnings默认为false,你可能会遇到即使没有配置warnings: true,控制台仍显示警告,看下面这段源码就知道了。查看源码

只有当options.compress !== false时 warnings 才会被设置默认值 false,所以一旦配置了 compress 其它选项,那就需同时配置warnings: false。

warnings作用是当插件在压缩过程中移除的无效代码或定义是显示警告信息(display warnings when dropping unreachable code or unused declarations etc.)。

提取CSS

使用extract-text-webpack-plugin插件提取CSS。更改 css 及 less 的 loader 配置如下。

// 安装插件

npm i extract-text-webpack-plugin -D
// var ExtractTextPlugin = require("extract-text-webpack-plugin")

{

  test: /\.css$/,

  use: ExtractTextPlugin.extract({

    use: "css-loader"

  })

},

{

  test: /\.styl$/,

  use: ExtractTextPlugin.extract({

    use: ["css-loader", "stylus-loader"]

  })

}

上述配置并不能提取 vue 文件中的 style,需要设置 vue-loader 参数才可以。

{

  test: /\.vue$/,

  use: {

    loader: "vue-loader",

    options: {

      loaders: {

        css: ExtractTextPlugin.extract({

          use: 'css-loader'

        }),

        stylus: ExtractTextPlugin.extract({

          use: ["css-loader", "stylus-loader"]

        })

      }

    }

  }

}

初始化插件,filename 可以指定 CSS 文件的目录。

new ExtractTextPlugin({

  filename: "css/style.css"

})

PostCSS

安装 postcss-loader 及 postcss 插件。

npm i postcss-loader cssnano -D

配置 loader 如下:

// css-loader配置改为

use: ['css-loader', "postcss-loader"]

// stylus-loader配置改为

use: ["css-loader", "postcss-loader", "stylus-loader"]

postcss-loader 要放在 css-loader 和 style-loader 之后,CSS 预处理语言 loader 之前(stylus-loader)。

新增 postcss.config.js 来配置postcss插件,这样就不用给每个 postcss-loader 去配置。更多 postcss-loader 的配置方式请参考 postcss-load-config。

module.exports = {

  plugins: [

    require('cssnano')

  ]

}

cssnano 使用了一系列 postcss 插件,包含了常用的 autoprefixer 等,如何传入 autoprefixer 的配置?

require('cssnano')({

  autoprefixer: {

    add: true,

    browsers: ['> 5%']

  }

})

其中有一个插件 postcss-zindex 使用中发现有些问题。如果想禁用这个插件的话,配置如下:

require('cssnano')({

  zindex: {

    disable:true

  }

})

附:postcss插件分类搜索网站:http://postcss.parts/

生成首页

安装 html-webpack-plugin 插件。

npm i html-webpack-plugin -D

初始化插件。

// var HtmlWebpackPlugin = require('html-webpack-plugin');

new HtmlWebpackPlugin({

  filename: 'index.html',

  template: 'index.tpl.html'

})

其它插件

Webpack3 新增的作用域提升。

new webpack.optimize.ModuleConcatenationPlugin()

指定生产环境,以便在压缩时可以让 UglifyJS 自动删除代码块内的警告语句。

new webpack.DefinePlugin({

  'process.env.NODE_ENV': JSON.stringify('production')

})

因为这个插件直接做的文本替换,给定的值必须包含字符串本身内的实际引号。通常,有两种方式来达到这个效果,使用 '"production"', 或者使用 JSON.stringify('production')。

你完全可以在自己的代码中使用process.env.NODE_ENV来区分开发和生产,从而针对不同的环境做一些事情。不用担心这部分代码会被保留,最终会被 UglifyJS 删除。例如:

if (process.env.NODE_ENV != "production") {

  // 开发环境

}

// webpack.DefinePlugin插件替换后,上述代码会变成

if ("production" != "production") {

  // 开发环境

}

// 输出

if (false) {

  // 开发环境

}

// UglifyJS 会删除这段无效代码

使用上述插件后再次构建,会发现生成的JS相比原来的体积小了不少。

friendly-errors-webpack-plugin 是一个更友好显示 webpack 错误信息的插件。插件 github 地址:https://github.com/geowarin/friendly-errors-webpack-plugin

一般在开发环境下使用。

var FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');

 

var webpackConfig = {

 // ...

 plugins: [

  new FriendlyErrorsWebpackPlugin(),

 ],

 // ...

}

效果如下图:

显示构建进度插件:webpack.ProgressPlugin

{

 // ...

 plugins: [

  new webpack.ProgressPlugin(),

 ],

 // ...

}

效果如下图:

美化 webpack 编译控制台打印的信息的插件webpack-dashboard

分离Webpack配置

将开发和生产配置文件分离,方便增加各个环境下的个性配置。Webpack2文档中也详细阐述了如何为多环境配置webpack。基本思路如下:

  1. 编写一个基本配置文件(webpack.base.config.js)

  2. 使用webpack-merge合并这个基础配置和针对环境的特定的配置(webpack.dev.config.js,webpack.prod.config.js)

webpack.base.config.js 内容如下:

var webpack = require('webpack');

var path = require('path');

var utils = require('./utils');

function resolve(relPath) {

  return path.resolve(__dirname, relPath);

}

module.exports = {

  entry: { app: resolve('../src/main.js') },

  output: {

    filename: 'js/[name].js'

  },

  module: {

    rules: [{

        test: /\.js$/,

        use: "babel-loader",

        include: [resolve('../src')]

      },

      {

        test: /\.vue$/,

        use: {

          loader: "vue-loader",

          options: utils.vueLoaderOptions()

        }

      },

      {

        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,

        use: {

          loader: "url-loader",

          options: {

            limit: 10000,

            name: 'images/[name].[hash:7].[ext]'

          }

        }

      },

      {

        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,

        use: [{

          loader: "url-loader",

          options: {

            limit: 10000,

            name: 'fonts/[name].[hash:7].[ext]'

          }

        }]

      }

    ]

  }

}

为什么要将vue-loader的options提取出来?其主要是用来配置CSS及CSS预处理语言的loader,开发环境可以不用配置,但是生产环境需要提取CSS、增加postcss-loader等,因此需要提取出来针对不同环境返回相应的options。后面会列出utils.vueLoaderOptions的内容。

为什么没有配置CSS的loader?理由和上面的vue-loader一样。

为什么没有配置path和publicPath?一方面是个性化参数,另外开发和生产可能不相同,因此在webpack.dev.config和webpack.prod.config中分别配置更为合适。

webpack.dev.config.js 内容如下:

var webpack = require('webpack');

var merge = require('webpack-merge');

var HtmlWebpackPlugin = require('html-webpack-plugin');

var baseWebpackConfig = require('./webpack.base.config');

var utils = require('./utils');

var config = require('./config');

Object.keys(baseWebpackConfig.entry).forEach(function(name) {

  baseWebpackConfig.entry[name] = [

    `webpack-dev-server/client?http://localhost:${config.dev.port}/`,

    "webpack/hot/dev-server"

  ].concat(baseWebpackConfig.entry[name])

});

module.exports = merge(baseWebpackConfig, {

  output: {

    path: config.dev.outputPath,

    publicPath: config.dev.outputPublicPath

  },

  module: {

    rules: utils.styleLoaders()

  },

  plugins: [

    new webpack.HotModuleReplacementPlugin(),

    new HtmlWebpackPlugin({

      filename: 'index.html',

      template: 'index.html',

      inject: true

    })

  ]

})

添加了HtmlWebpackPlugin后,index.html中就不需要在自己去引用打包的JS了,会自动根据打包的JS添加引用,这样更加方便,关于HtmlWebpackPlugin的配置,需要说明两点:

1.template的路径是相对于webpack编译时的上下文目录,说白了就是项目根目录,因此上面可以直接配置index.html,其指向的就是根目录下的index.html;

2.filename则是相对于webpack配置项output.path(打包资源存储路径)。

html-webpack-plugin关于template和filename路径源码如下:

// https://github.com/jantimon/html-webpack-plugin/blob/master/index.js

// template

this.options.template = this.getFullTemplatePath(this.options.template, compiler.context);

// filename

this.options.filename = path.relative(compiler.options.output.path, filename);

config.js内容如下:

module.exports = {

  dev: {

    outputPath: path.resolve(__dirname, '../static'),

    outputPublicPath: '/',

    port: 8000

  },

  prod: {

    outputPath: path.resolve(__dirname, '../static'),

    outputPublicPath: '/static/'

  }

}

utils.js内容如下:

var ExtractTextPlugin = require('extract-text-webpack-plugin');

var isProd = process.env.NODE_ENV === "production";

// 根据项目需求添加CSS预处理语言并安装相应的loader,以stylus-loader为例

var cssLang = [{

  name: 'css',

  reg: /\.css$/,

  loader: 'css-loader'

}, {

  name: 'stylus',

  reg: /\.styl$/,

  loader: "stylus-loader"

}];

function genLoaders(lang) {

  var loaders = ['css-loader', 'postcss-loader'];

  if (lang.name !== 'css') {

    loaders.push(lang.loader);

  }

  if (isProd) {

    // 生产环境需要提取CSS

    loaders = ExtractTextPlugin.extract({

      use: loaders

    });

  } else {

    // 开发环境需要vue-style-loader将CSS提取到页面头部

    loaders.unshift('vue-style-loader');

  }

  return loaders;

}

// 各种CSS的loader

exports.styleLoaders = function() {

  var output = [];

  cssLang.forEach(lang => {

    output.push({

      test: lang.reg,

      use: genLoaders(lang)

    })

  })

  return output;

};

// vue-loader的options

exports.vueLoaderOptions = function() {

  var options = {

    loaders: {}

  };

  cssLang.forEach(lang => {

    options.loaders[lang.name] = genLoaders(lang);

  });

  return options;

}

接下来就是如何启动webpack-dev-server,vue-cli的webpack模板工程用的express及webpack中间件做开发服务器,其实用webpack-dev-server就能满足需求,当然用express能够做更多的事情,毕竟webpack-dev-server是一个轻量级的express。dev.js内容如下:

var webpack = require('webpack');

var webpackDevServer = require('webpack-dev-server');

var devConfig = require("./webpack.dev.config");

var config = require("./config");

var compiler = webpack(devConfig);

var server = new webpackDevServer(compiler, {

  hot: true,

  noInfo: true,

  publicPath: config.dev.outputPublicPath,

  stats: { colors: true }

});

server.listen(config.dev.port, "0.0.0.0");

var url = `http://localhost:${config.dev.port}/`;

// 需先安装 opn 模块 npm i opn -D

var opn = require('opn');

// 打包完毕后启动浏览器

server.middleware.waitUntilValid(function() {

  console.log(`> Listening at ${url}`);

  opn(`${url}`);

})

生产配置文件(webpack.prod.config.js)内容如下:

// 设定为生产环境

process.env.NODE_ENV = 'production';

var webpack = require('webpack');

var merge = require('webpack-merge');

var HtmlWebpackPlugin = require('html-webpack-plugin');

var ExtractTextPlugin = require('extract-text-webpack-plugin');

var baseWebpackConfig = require('./webpack.base.config');

var utils = require('./utils');

var config = require('./config');

 

module.exports = merge(baseWebpackConfig, {

  output: {

    path: config.prod.outputPath,

    publicPath: config.prod.outputPublicPath

  },

  module: {

    rules: utils.styleLoaders()

  },

  plugins: [

    new webpack.DefinePlugin({

      'process.env.NODE_ENV': '"production"'

    }),

    new webpack.optimize.UglifyJsPlugin(),

    new ExtractTextPlugin({

      filename: "css/style.css?[contenthash:8]"

    }),

    new HtmlWebpackPlugin({

      filename: 'index.html',

      template: 'index.html',

      inject: true

    })

  ]

})

生产构建(prod.js)内容如下:

var webpack = require("webpack");

var webpackProdConfig = require('./webpack.prod.config');

webpack(webpackProdConfig, function(err, stats) {

  process.stdout.write(stats.toString());

});

对应在package.json中添加开发和生产构建的命令如下:

"scripts": {

  "dev": "node build/dev.js",

  "build": "node build/prod.js"

}

代码分割

参照vue-cli及webpack文档的提取公共代码的方式,利用插件webpack.optimize.CommonsChunkPlugin将来自node_modules下的模块提取到vendor.js(一般来讲都是外部库,短时间不会发生变化)。于是有如下代码:

new webpack.optimize.CommonsChunkPlugin({

  name: 'vendor',

  minChunks: function(module, count) {

    return module.resource && /\.js$/.test(module.resource) && module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0

  }

})

如果你查看未压缩版的vendor.js,会发现不仅包含vue的代码,还包含了webpackBootstrap(webpack模块加载器)的代码,按理说放在vendor里面也没啥问题,毕竟后面的模块都需要依赖于此,但是如果你的chunk使用了hash,一旦app代码发生了改变,相应的hash值会发生变化,webpackBootstrap的代码也会发生变化(如图),而我们提取vendor的初心就是这部分代码改变频率不大,显然这不符合我们的目标,那么应当将webpackBootstrap再提取到一个文件中,代码如下:

new webpack.optimize.CommonsChunkPlugin({

  name: 'manifest',

  chunks: ['vendor']

})

 

用 import 还是 require

vue 2.2.0 后不能直接使用 require 来加载 vue,那么到底改是该使用 ES6 Module 还是 CommonJS 呢?,先看一个对比图:

全部使用 ES6 Module,即import、export default,最终打包的app.js为1.20KB。

全部使用 CommonJS(除了vue),即require、module.exports,最终打包的app.js为1.12KB。

虽然两者大小相差不大,但是这不禁让人觉得用 CommonJS 似乎是一条优化措施,那么代码层面到底是怎么回事呢?

为了一探究竟,注释了压缩插件,以about.vue最终构建的代码来看,使用 CommonJS 的代码如下:

 (function (module, exports, __webpack_require__) {

 "use strict";

 module.exports = {

  data: function data() {

   return {

    page: 'about'

   };

  }

 };

}),

这基本上和 about.vue 中的代码相差无几,而使用 ES6 Module 构建的代码如下:

(function (module, exports, __webpack_require__) {

 "use strict";

 Object.defineProperty(exports, "__esModule", {

  value: true

 });

 exports.default = {

  data: function data() {

   return {

    page: 'about'

   };

  }

 };

}),

对比两种规范下构建后的代码,使用 ES6 Module 主要是多了 Object.defineProperty 那一部分,从而导致了最终打包的文件大一点儿。那是不是为了最终文件体积能小些就全部使用 CommonJS 呢?这个需要你充分理解 CommonJS 和 ES6 Module 的区别,引用《ECMAScript 6入门》这本书的解释如下:

ES6模块加载的机制,与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝,而ES6模块输出的是值的引用。

为了更清楚的理解这段话,我们稍微做一下测试,在 src 下增加一个test.js,内容如下(分别将两种写法列出):
 

// CommonJS

var counter = 1;

function incCounter() {

  counter++;

}

module.exports = {

  counter: counter,

  incCounter: incCounter,

};

// ES6 Module

export let counter = 1;

export function incCounter() {

  counter++;

}

在about.vue中测试如下:

 // CommonJS

var test = require('../test');

export default {

  created() {

    console.log(test.counter); // 1

    test.incCounter();

    console.log(test.counter); // 1

  }

}

// ES6 Module

import { counter, incCounter } from '../test';

export default {

  created() {

    console.log(counter); // 1

    incCounter();

    console.log(counter); // 2

  }

}

最终的输出值也印证了前面的解释,更详细的解读请查阅相关资料或书籍。只有深入理解了两者的区别,自然就能明白何时该使用何种规范。当然 ES6 作为未来的趋势,我们应该去做更多的尝试。

异步组件(懒加载)

之前用懒加载的方式是:require.ensure,在 webpack2 中引入了 Code Splitting-Async 的新方法 import(),用于动态引入 ES Module。require.ensure 可以指定 chunkFilename,但是 import 没有很好的途径去指定,webpack3 为了解决这个问题,提出了用魔法注释的方式来指定模块名。

结合 vue-router 可以轻松实现懒加载,配置路由指向异步组件即可实现懒加载,比如:

{

    path: '/async',

    component: () => import(/* webpackChunkName: "async" */'./views/async.vue')

}

如果你发现使用 import() 运行时报错,有几种情况:
1.babel presets 配置为 es2015,则不支持动态导入功能,因此需要安装支持动态导入的 presets(npm i babel-preset-stage-2 -D),或者 babel 插件(npm i babel-plugin-syntax-dynamic-import -D);
2.babel presets 配置为 env,但是 modules 配置为 false,babel 则不会解析 import,可以安装插件 (npm i babel-plugin-syntax-dynamic-import -D)解决。

魔法注释虽然指定了块名,但是 webpack 默认的块名配置为 [id].js,即用的模块的 id 作为块名,因此需要我们手动改下配置。

修改 webpack.base.config.js 的 output:

output: {

  filename: 'js/[name].js',

  chunkFilename: "js/[name].[chunkhash].js"

}

效果如下图:

 

如果发现魔法注释没有生效,要检查下 .babelrc 的配置项 comments 是否设为 true。或者不配置 comments(默认为true)

extract-text-webpack-plugin 默认不会提取异步模块中的 CSS,需要加上配置:

new ExtractTextPlugin({

  allChunks:true,

  filename: "css/style.css?[contenthash:8]"

})

相关推荐:

webpack和vue2构建vue项目骨架讲解

关于vue2.0设置proxyTable使用axios进行跨域请求

简单了解vue2 单页面如何设置网页title

以上是建置vue2 vue-router2 webpack3 工程教學的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
C和JavaScript:連接解釋C和JavaScript:連接解釋Apr 23, 2025 am 12:07 AM

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

從網站到應用程序:JavaScript的不同應用從網站到應用程序:JavaScript的不同應用Apr 22, 2025 am 12:02 AM

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python vs. JavaScript:比較用例和應用程序Python vs. JavaScript:比較用例和應用程序Apr 21, 2025 am 12:01 AM

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C/C在JavaScript口譯員和編譯器中的作用C/C在JavaScript口譯員和編譯器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用