499
0

[WordPress] Tích hợp Vue JS với Gulp và Webpack

499
Thời gian đọc: 7 phút

Hiện nay có rất nhiều library và framework JavaScript cho Frontend  như: React JS, Vue JS, Svelte js, Angular JS,… Thì viêc kết hợp vào WordPress là điều không thế tránh khỏi. Với bài viết này Wolfactive sẽ mang đến các bạn cách tích hợp Vue JS vào WordPress.

Vue JS là gì ?

Vue JS là một framwork JavaScript dùng để xây dựng giao diện người dùng cho trang web. Khác với React JS thì Vue JS được thiết kế từ đầu theo hướng cho phép và khuyến khích việc phát triển ứng dụng theo từng bước. Khi phát triển lớp giao diện (view layer), người dùng chỉ cần dùng thư viện lõi (core library) của Vue, rất dễ học và tích hợp với các thư viện hoặc dự án có sẵn.

Tham khảo thêm tại https://vi.vuejs.org/v2/guide/

Vue JS và WordPress

Hiện tại có rất nhiều các để tích hợp Vue JS vào WordPress như:

👉 Sử dụng WordPress như một Headless CMS (CMS sử dụng giao diện từ bên ngoài), Ngoài giao diện Vue JS chỉ cần gọi API để tải dữ liệu có thể làm với (NUXT JS, VUETIFY, VUEX,..)

👉 Enqueue library Vue Js vào WordPress sau đó viết Vue tích hợp với PHP để làm giao diện

👉 Ngoài ra còn một số stater theme Vue JS khác có trên github các bạn có thể lấy về và sử dụng

👉 Hoặc mua theme có sẵn Vue để sử dụng 😁 😁

 

Nhưng với bài này Wolfactive sẽ hướng dẫn các bạn tích hợp Vue JS bằng Gulp và Webpack

👉 Dễ dàng xây dựng trang web theo dạng SPA chạy được trên nền WordPress

👉 Có thể xài chung với các node package khác,

👉 Viết JS theo kiểu ES6

👉 …

Cấu hình tích hợp Vue JS

Để tích hợp Vue JS vào WordPress chúng ta cần làm nhưng bước sau:

1. Khởi tạo theme WordPress

Trước tiên chúng ta cần tạo folder Theme trong  WordPress vào dường dẫn wp-content/themes/ tạo folder cho theme

cau-hinh-vue-js-vao-wordpress

Trong thư mục đó chứa theme ta tạo các file cần thiết của một theme WordPress: functions.php, header.php, footer.php,style.css,index.php

tich-hop-vue-js-vao-wordpress-cau-truc-theme

 Sau đó vào file style.css để khai báo theme

/*
Theme Name: Wolfactive
Theme URI: https://wolfactive.dev/
Author: Wolfactive team
Author URI: https://wolfactive.dev/
Description: This is theme Wolfactive
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: wolfactive
This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned with others.
*/

Sau đó khởi tạo file packages.json để cài các node packages, vue js, webpack,... (Nhớ cài node js). Bằng cách bật terminal tại folder của theme chạy lệnh

yarn init

Sau đó làm theo hướng trên termnial vậy là chúng ta đã khởi tạo xong packages.json. Các bạn copy phần này vào file packages.json

"devDependencies": { 
  "@babel/core": "^7.10.2", 
  "@babel/preset-env": "^7.10.2", 
  "@babel/register": "^7.10.1", 
  "autoprefixer": "^9.8.0", 
  "babel-loader": "^8.1.0", 
  "browser-sync": "^2.26.7", 
  "del": "^5.1.0", 
  "gulp": "^4.0.2", 
  "gulp-clean-css": "^4.3.0", 
  "gulp-header-license": "^1.0.10", 
  "gulp-if": "^3.0.0", 
  "gulp-imagemin": "^7.1.0", 
  "gulp-postcss": "^8.0.0", 
  "gulp-prettier": "^3.0.0", 
  "gulp-replace": "^1.0.0", 
  "gulp-sass": "^4.1.0", 
  "gulp-sourcemaps": "^2.6.5", 
  "gulp-wp-pot": "^2.4.3", 
  "gulp-zip": "^5.0.1", 
  "prettier": "2.2.1", 
  "vue-loader": "^15.9.6", 
  "vue-template-compiler": "^2.6.12", 
  "webpack-stream": "^5.2.1", "yargs": "^15.3.1" 
}, 
"dependencies": { 
  "core-js": "^3.10.1", 
  "vue": "^2.6.12", 
  "vue-router": "^3.5.1" 
},

Tiếp theo chạy lệnh yarn để cài các packages cần thiết. Sau khi cài xong chúng ta sẽ đi qua phần cấu hình gulp js

2. Gulp JS là gì ?  Cài đặt Gulp JS

Trước khi cấu hình Gulp JS chúng ta cần biết Gulp JS là gì và tại sao chúng ta lại cần nó. Gulp là bộ công cụ JavaScript mã nguồn mở của Fractal Innovations và cộng đồng nguồn mở tại GitHub, được sử dụng làm hệ thống xây dựng phát trực tuyến trong phát triển web front-end. Giúp chúng ta viết các task quản lý trong một project. Tiếp theo chúng ta sẽ cài đặt Gulp cho theme.

Tạo 2 file:

gulpfile.babel.js, .babelrc

Trong file .babelrc chúng ta diền các nội dung sau

{
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-proposal-class-properties"]
}

Tiếp tục trong file gulp.babel.js chúng ta sẽ tạo các hàm cơ bản trước. Để tái sử dụng cho các phần sau. Trước tiên mình import các package của gulp

import { src, dest, watch, series, parallel } from 'gulp'
<span class="k">import</span> <span class="nx">del</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">del</span><span class="dl">'</span>

Và mình sẽ tạo hàm copy file

export const copy = () => {
  return src([
    'src/**/*',
    '!src/{images,js,scss}',
    '!src/{images,js,scss}/**/*',
   ]).pipe(dest('dist'))
}

Hàm này giúp copy các file trong folder src sang folder dist.

Tiếp theo mình sẽ tạo hàm xóa files. Để tránh tình trạng bị cache nội dung khi ghi đè file cũ.

export const clean = () => del(['dist/js', 'dist/css/main.scss', 'dist/images'])

Hàm này có tác dụng xóa tất cả các file css, ảnh, js trong thư mục dist. 

3. Cấu hình biên dịch SCSS thành CSS

Sau khi đã tạo xong các hàm cơ bản chúng ta đi tới tạo hàm biên dịch scss thành css

Trước tiên import các module cần thiết

import yargs from 'yargs' 
import sass from 'gulp-sass' 
import cleanCss from 'gulp-clean-css' 
import gulpif from 'gulp-if' 
import postcss from 'gulp-postcss' 
import sourcemaps from 'gulp-sourcemaps' 
import autoprefixer from 'autoprefixer'

Sau đó chúng ta có hàm sau:

export const styles = () => { 
  return src('src/scss/main.scss') 
   .pipe(gulpif(!PRODUCTION, sourcemaps.init())) 
   .pipe(sass().on('error', sass.logError)) 
   .pipe(gulpif(PRODUCTION, postcss([autoprefixer]))) 
   .pipe(gulpif(PRODUCTION, cleanCss({ compatibility: 'ie8' }))) 
   .pipe(gulpif(!PRODUCTION, sourcemaps.write())) 
   .pipe(dest('dist/css')) 
   .pipe(server.stream()) 
}

Hàm này mình sẽ cho file scss chính vào sau đó kiểm tra nếu ở môi trường develop thì sẽ source map trong css để dễ dàng trong quá trình chỉnh sửa scss. Đồng thời sẽ in lỗi ra console log của terminal thông báo cho chúng ta dễ debug. Hai dòng tiếp theo sẽ kiểm tra nếu như là môi trường production (Môi trường hoạt động chính thức) thì sẽ tự prefix css và nén file css.

4. Cấu hình biên dich JS ES6 thành JS ES5

Sau khi cấu hình xong scss chúng ta viết hàm biên dịch JS ES6 thành ES5

Cũng như các phần trên chúng ta import các module cần thiết (webpack)

import webpack from 'webpack-stream'

Mình dùng wepback để sử lý tác vụ cho js đồng thời thêm babel js để convert từ es6 sang es5

export const scripts = () => { 
  return src('src/js/root.js') 
  .pipe( webpack({ module: 
     { rules: [ 
       { test: /\.js$/, 
         use: { 
              loader: 'babel-loader', 
              options: { 
                 presets: ['@babel/preset-env'], 
                        }, 
             }, 
       }, ], }, 
      mode: PRODUCTION ? 'production' : 'development', 
      devtool: !PRODUCTION ? 'inline-source-map' : false, 
      output: { filename: 'root.js', }, }) ) 
  .pipe(dest('dist/js')) }

5. Cấu hình nén ảnh

Chúng ta import các module cần thiết

<span class="k">import</span> <span class="nx">imagemin</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">gulp-imagemin</span><span class="dl">'</span>

export const images = () => { 
   return src('src/images/**/*.{jpg,jpeg,png,svg,gif}') 
  .pipe(gulpif(PRODUCTION, imagemin())) 
   .pipe(dest('dist/images')) 
}

Hàm này giúp chúng ta nén ảnh các bạn có thể search package này và coi document để cấu hình

6. Cấu hình tự động biên dịch ES6 và SCSS

Chúng ta import các module cần thiết vào

import browserSync from 'browser-sync'

Cấu hình proxy cho browserSync

const server = browserSync.create() 
export const serve = (done) => { 
 server.init({ 
    proxy: 'http://wolfactive.local', 
  // put your local website link here 
  }) 
  done() 
}

Hàm tự động biên dịch và các hàm bổ trợ

export const reload = (done) => { server.reload() done() }

Hàm này dùng để reload browser

export const watchForChanges = () => { 
  watch('src/scss/**/*.scss', styles) 
  watch('src/images/**/*.{jpg,jpeg,png,svg,gif}', series(images, reload)) 
  watch( ['src/**/*', '!src/{images,js,scss}', '!src/{images,js,scss}/**/*'], series(copy, reload) ) 
  watch(['src/js/**/*.js', 'src/js/**/*.vue'], series(scripts, reload)) 
  watch('**/*.php', reload) }

7. Tích hợp Vue JS

Chúng ta import các module cần thiết vào

<span class="k">import</span> <span class="nx">VueLoaderPlugin</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">vue-loader/lib/plugin</span><span class="dl">'</span>

Sửa lại một tý hàm biên dịch JS

export const scripts = () => { 
   return src('src/js/root.js') 
   .pipe( webpack({ module: 
          { rules: [ { 
           test: /\.js$/, use: { 
            loader: 'babel-loader', 
            options: { presets: ['@babel/preset-env'], 
              }, }, }, { test: /\.vue$/, loader: 'vue-loader', }, ], }, 
              plugins: [new VueLoaderPlugin()], 
              resolve: { alias: { vue$: 'vue/dist/vue.runtime.esm.js', }, 
                   extensions: ['*', '.js', '.vue', '.json'], }, 
              mode: PRODUCTION ? 'production' : 'development', 
            devtool: !PRODUCTION ? 'inline-source-map' : false, 
            output: { filename: 'root.js', }, }) ) 
   .pipe(dest('dist/js')) }

8. Xây dựng lệnh chạy môi tường dưới local và trên server (bundle theme)

Chúng ta import các module cần thiết vào

import info from './package.json' 
import wpPot from 'gulp-wp-pot'

Các hàm để đóng gói và tạo lệnh để sử dụng

export const pot = () => { 
  return src('**/*.php') 
   .pipe( wpPot({ domain: '_themename', package: info.name, }) ) 
   .pipe(dest(`languages/${info.name}.pot`)) }
export const dev = series( clean, parallel(styles, images, copy, scripts), serve, watchForChanges ) 
export const build = series(clean, parallel(styles, images, copy, scripts), pot) 
export default dev

Sau đó vào packages.json tạo các lệnh sau:

"scripts": { 
 "start": "prettier --write . && gulp", 
 "beauty": "prettier --write .", 
 "build": "gulp build --prod" 
},

Như vậy các bạn dùng yarn start để chạy môi trường develop, yanr beauty để làm đẹp code và yanr build để đóng gói sản phẩm

Các bạn có thể tham khảo 2 đầy đủ file gulp.babel.jspackages.json của mình ở 2 đường link sau:

gulp.babel.js:  https://gist.github.com/Canvilled/54b35d9c62fecbfb4aee327b1bf2a1ba

packages.json: https://gist.github.com/Canvilled/162397ea128f9059719e3f7e0cfada05

9. Hướng dẫn kết nối Vue JS và WordPress

Để có thể đổ dữ liệu vào Vue JS thì trước tiên các bạn vào file functions.php tạo hook vào wp-header render json cho Vue JS và enqueue  css và js cho theme

class Settings_Admin { 
  public function __construct() { 
     <span class="pl-en">add_action</span>( <span class="pl-s">'wp_head'</span>, <span class="pl-en">array</span>(<span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>, <span class="pl-s">'add_script_to_fe'</span>) );
    add_action( 'admin_enqueue_scripts', array($this, 'add_custom_style_script') ); 
    add_filter( 'script_loader_tag', array($this,'defer_js'), 10,2 ); 
  }
 public function add_custom_style_script(){
   wp_register_style('wa_email_marketing', PLUGIN_URL . '/dist/css/main.css');
   wp_enqueue_style('wa_email_marketing');
  wp_register_script('wa_email_marketing', PLUGIN_URL . '/dist/js/root.js');
 } 
public function defer_js($tag, $handle){
  $scripts_to_defer = array('wa_email_marketing'); 
  foreach($scripts_to_defer as $defer_script) {
    if ($defer_script === $handle) {
   return str_replace(' src', ' defer src', $tag);
  }
 }
 return $tag;
}
 public function add_script_to_fe(){
  $script = 'var apiObject = "' . wp_json_encode(
   array(
    'homeUrl' => home_url(),
    'rootapiurl' => rest_url(),
    'nonce' => wp_create_nonce('wp_rest'),
    'plugin_url' => PLUGIN_URL,
    'user_id' => get_current_user_id(),
    )) . '";';
   if ( ! empty( $data ) ) {
   $script = "$data\n$script";
   }
  _e("\n<script type=\"text/javascript\">\n $script \n</script>\n",'_themename');
 }
}

Sau đó các bạn ra ngoài index.php tạo thẻ div : <div id=”root”></div>

Và các bạn vào file src/js/root.js

import Vue from 'vue' 
import App from './App.vue' 
new Vue({ router, 
     render: (h) => h(App), 
     mounted() {}, 
}).$mount('#root')

Taọ file App.vue cùng thư mục các bạn có thể viết Vue Js như bình thường.

Full code file functions.phphttps://gist.github.com/Canvilled/2772158c8e43fddce63f8f8a3edfea57

Tổng kết

Với bài viết này mình đã hướng dẫn các bạn cách cấu hình Vue Js vào WordPress ở bài viết tới mình sẽ hướng dẫn các bạn cách config cấu hình React Js vào WordPress.

Hy vọng các bạn sẽ theo dõi. Nếu các bạn có thắc mắc gì thì hãy gửi thông tin, đóng góp vào fanpage Wolfactive tụi mình nhé.