Memindahkan addon Ember ke format v2
Menuju edisi Polaris, satu perubahan besar telah diumumkan di dunia Ember JS: Embroider, sistem build generasi berikutnya yang bertujuan untuk menjembatani kesenjangan antara Ember dan ekosistem JS yang lebih luas, menghasilkan banyak manfaat setelah diadopsi. Seperti yang disebutkan dalam RFC -nya :
- add-on yang kurang "khusus", yang hanya akan menjadi paket NPM biasa
- build yang lebih cepat dan pemasangan NPM.
- dapat memanfaatkan alat build yang ada seperti Webpack atau Vite
- membawa fitur-fitur penting yang sudah lama tidak dimiliki oleh ekosistem Ember seperti pengguncangan pohon dan pemecahan kode
Konteks
Addon yang saya kerjakan mencakup fitur-fitur berikut:
- Naskah
- Jasa
- Adaptor Data Ember, model, serializer
- Komponen (campuran Glimmer dan Ember Classic)
- Terjemahan (didukung oleh ember-intl )
- Beberapa aset publik (gambar) yang digunakan dalam komponen perlu disalin ke aplikasi induk
- Beberapa CSS (diproses sebelumnya menggunakan Less )
Juga, ini adalah pertama kalinya saya harus bekerja dengan monorepos (Ruang Kerja Benang di sini) sehingga beberapa masalah yang saya hadapi mungkin terkait dengan kurangnya pengetahuan saya tentangnya.
Menjalankan codemod
Jika belum selesai, saya sangat menyarankan Anda membaca panduan migrasi untuk mem-porting addons v1 ke format v2 karena memberikan banyak penjelasan tentang pohon file baru.
Untungnya, sejak format v2 diperkenalkan, beberapa codemods telah ditulis oleh komunitas untuk mempercepat prosesnya dan saya menggunakan ember-codemod-v1-to-v2 ( ember-addon-migrator juga merupakan opsi tetapi saya melakukannya belum mengujinya).
npx [email protected] --addon-location="packages/addon" --test-app-location="packages/test-app"
- paket addon: ini adalah kode add-on Anda yang sebenarnya yang Anda harapkan disediakan untuk aplikasi induk
- paket aplikasi uji, membawa peran yang sama dengan aplikasi dummy dalam format v1.
- membangun addon (termasuk dalam mode jam tangan)
- jalankan server aplikasi pengujian
- jalankan pengujian di aplikasi pengujian
Berurusan dengan terjemahan
Menggunakan ember-intl, ada translationsdirektori di root proyek yang ditinggalkan oleh codemod, menyebabkan hilangnya terjemahan jika diperlukan. Untuk memperbaikinya, saya hanya perlu memindahkan translationsdirektori ke root paket addon, lalu mencantumkannya di kolom `files` packages/my-addon/package.jsonsehingga dipublikasikan dan tersedia untuk aplikasi induk.
{
"name": "my-addon",
"version": "0.0.13",
"keywords": [
"ember-addon"
],
...,
"files": [
"addon-main.cjs",
"dist",
"translations"
]
}
Karena addon dikirim dengan adaptor Ember Data, itu perlu dikonfigurasi untuk mencapai host backend yang tepat tergantung pada lingkungan aplikasi induk yang sedang berjalan.
Sebelumnya, kita akan melakukannya seperti ini:
import { getOwner } from '@ember/application';
export default class BaseAdapter extends AuthorizedAdapter {
get namespace(): string {
return 'api/v1';
}
get host(): string {
const config = getOwner(this).resolveRegistration('config:environment')['my-addon'];
return config.backendURL;
}
}
Sayangnya, ini tidak berfungsi lagi karena format v2 adalah tentang lebih sedikit keajaiban dan lebih sedikit keajaiban waktu pembuatan. Tapi itu masih mungkin menggunakan @embroider/macros. Dengan menggunakan paket ini, saya dapat mengonfigurasi host yang tepat hanya dengan memperbarui confignilai objek:
import { getOwnConfig } from '@embroider/macros';
export default class BaseAdapter extends AuthorizedAdapter {
get namespace(): string {
return 'api/v1';
}
get host(): string {
return (getOwnConfig() || {}).backendURL;
}
}
module.exports = function (defaults) {
let app = new EmberAddon(defaults, {
'@embroider/macros': {
setConfig: {
'my-addon': {
backendURL: process.env.BACKEND_URL || 'https://some-default.api.io'
}
}
}
});
}
Menyediakan aset publik
Setelah menautkan addon di aplikasi yang benar-benar menggunakannya, saya perhatikan bahwa semua gambar yang biasanya disertakan dengannya tidak ada di build aplikasi.
Ternyata, file-file di folder addon public(yang harus dipindahkan ke packages/my-addon/public) harus terdaftar di objek meta addon package.jsondalam ember-addon.public-assetsformat berikut:
{
"name": "my-addon",
"version": "0.0.13",
"keywords": [
"ember-addon"
],
"ember-addon": {
...,
"public-assets": {
"./public/assets/images/tomster.png": "/my-addon/assets/images/tomster.png",
"./public/assets/images/zoey.svg": "/my-addon/assets/images/zoey.svg"
}
}
...
}
Namun, meskipun ini bisa sangat cepat untuk addon yang hanya menyediakan beberapa aset publik, itu bisa lepas kendali jika jumlahnya banyak, jadi ada permintaan tarik terbuka untuk menambahkan plugin Rollup bawaan yang menjaga ember-addon.public-assetsobjek meta tetap sinkron dengan publicdirektori.
Menangani CSS
Seperti yang dinyatakan sebelumnya, addon ini menyediakan beberapa komponen beserta CSS-nya, diproses sebelumnya menggunakan Less CSS. Saya juga tidak memiliki komponen yang mengimpor CSS mereka sendiri sebelumnya, melainkan file entrypoint addon/styles/addon.lessyang mengimpor file relatif lainnya. Untuk menghindari melalui semua komponen dan menempatkan CSS mereka di sebelahnya, saya memilih untuk melanjutkan dengan satu file CSS untuk saat ini. Jadi saya memiliki dua masalah untuk ditangani pada saat ini:
- CSS yang tidak diimpor dari file JS akan dihilangkan
ember-cli-lesstidak berfungsi lagi untuk menangani lebih sedikit file
{
"name": "my-addon",
"version": "0.0.13",
"keywords": [
"ember-addon"
],
...,
"exports": {
".": "./dist/index.js",
"./*": {
"types": "./dist/*.d.ts",
"default": "./dist/*.js"
},
"./addon-main.js": "./addon-main.cjs",
"./styles": "./dist/styles/_addon.css",
},
}
import Application from '@ember/application';
import Resolver from 'ember-resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
import 'my-addon/styles';
export default class App extends Application {
modulePrefix = config.modulePrefix;
Resolver = Resolver;
}
loadInitializers(App, config.modulePrefix);
- dalam hal refactoring: Anda memiliki segalanya di samping satu sama lain
- itu membuat tree-shaking lebih mudah dan Anda tidak akan mengirim CSS mati ke browser
import { readFileSync, writeFileSync } from 'fs';
import less from 'less';
import { Addon } from '@embroider/addon-dev/rollup';
const addon = new Addon({
srcDir: 'src',
destDir: 'dist'
});
export default {
// This provides defaults that work well alongside `publicEntrypoints` below.
// You can augment this if you need to.
output: addon.output(),
plugins: [
// Made sure to do the preprocessing before the keepAssets plugin is ran.
{
name: 'less-handler',
generateBundle() {
const lessCode = readFileSync('src/styles/main.less', 'utf-8');
less.render(
lessCode,
{
paths: ['src/styles']
},
(err, rendered) => {
if (err) {
console.log(err);
return;
}
const css = rendered.css;
const filename = path.join('src', 'styles', '_addon.css');
mkdirp.sync(path.dirname(filename));
writeFileSync(filename, css);
}
);
}
},
// addons are allowed to contain imports of .css files, which we want rollup
// to leave alone and keep in the published output.
addon.keepAssets(['**/*.css']),
// Remaining plugins from the sample file
]
};
Penyelesaian masalah
Ini adalah beberapa masalah yang mudah diperbaiki setelah menjalankan codemod:
- bidang deklarasi pertama-tama harus diubah oleh @babel/plugin-transform-typescript. Diperbaiki dengan mengaktifkan
allowDeclareFieldsopsi (https://babeljs.io/docs/babel-preset-typescript#allowdeclarefields) - Saat mengganti impor lama (dengan nama paket sebagai root) dengan impor relatif, codemod secara tidak sengaja mengganti jalur aset yang dibangun secara dinamis di beberapa komponen dengan impor relatif, merusak beberapa jalur gambar. Pemeriksaan ganda cepat mungkin diperlukan di sini
- bara-impor-otomatis
css-loadergagal menangani url dengan jalur relatif. Ini adalah masalah umum dengan Webpack yang saya alami bahkan di luar konteks migrasi ini. Untuk saat ini, pengaturanautoImport.cssLoaderOptions.urlkefalse(lih.https://webpack.js.org/loaders/css-loader/#url) memperbaiki masalah.

![Apa itu Linked List? [Bagian 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































