IT |
ITmedia 総合記事一覧 |
[ITmedia ビジネスオンライン] 「エンジン音」「振動」などをどう残すか EVスポーツカー模索 |
https://www.itmedia.co.jp/business/articles/2301/27/news082.html
|
試行錯誤 |
2023-01-27 00:30:00 |
Ruby |
Rubyタグが付けられた新着投稿 - Qiita |
Rubyで本気で考えるnil safe |
https://qiita.com/fumi_blog/items/484eaf5d510ffc5b1297
|
personattraccessorfirstna |
2023-01-27 00:50:17 |
AWS |
AWSタグが付けられた新着投稿 - Qiita |
ChatGPTを試してみた |
https://qiita.com/k_suzuki527/items/389a9815b03041617d9e
|
chatgpt |
2023-01-27 00:56:51 |
Azure |
Azureタグが付けられた新着投稿 - Qiita |
ChatGPTを試してみた |
https://qiita.com/k_suzuki527/items/389a9815b03041617d9e
|
chatgpt |
2023-01-27 00:56:51 |
Ruby |
Railsタグが付けられた新着投稿 - Qiita |
Rubyで本気で考えるnil safe |
https://qiita.com/fumi_blog/items/484eaf5d510ffc5b1297
|
personattraccessorfirstna |
2023-01-27 00:50:17 |
技術ブログ |
Mercari Engineering Blog |
メルカリにおける機械学習による検索のリランキングへの道のり |
https://engineering.mercari.com/blog/entry/20230101-the-journey-to-machine-learned-re-ranking/
|
hellip |
2023-01-26 16:30:59 |
海外TECH |
Ars Technica |
By learning to hunt otters, wolves decimate a deer population |
https://arstechnica.com/?p=1912626
|
aquatic |
2023-01-26 15:15:41 |
海外TECH |
MakeUseOf |
EXE vs MSI Files: What Are the Differences? |
https://www.makeuseof.com/exe-msi-differences/
|
differences |
2023-01-26 15:15:16 |
海外TECH |
DEV Community |
Configuring the KubernetesPodOperator on Managed Workflows for Apache Airflow (MWAA) - non OIDC Amazon EKS Clusters |
https://dev.to/aws/configuring-the-kubernetespodoperator-on-managed-workflows-for-apache-airflow-mwaa-non-oidc-amazon-eks-clusters-1hbg
|
Configuring the KubernetesPodOperator on Managed Workflows for Apache Airflow MWAA non OIDC Amazon EKS ClustersToday I came across an interesting question around the use of the KubernetesPodOperator working on EKS Clusters where you have not configured OIDC They had followed my blog post and when it came to running the DAG they got the following error UTC kubernetes pod py INFO Creating pod mwaa pod test ababbaafef with labels dag id kubernetes pod example iam authenticator task id pod task execution date T cadb try number UTC kubernetes pod py ERROR Reason UnauthorizedHTTP response headers HTTPHeaderDict Audit Id ae bee b acc Cache Control no cache private Content Type application json Date Thu Jan GMT Content Length HTTP response body kind Status apiVersion v metadata status Failure message Unauthorized reason Unauthorized code As I still had the environment I built from this blog post I decided to see if I could reproduce the problem I built a new EKS Cluster following the same instructions EXCEPT the initial EKS Cluster creation which I used the following eksctl create cluster name mwaa eks region eu central version nodegroup name linux nodes nodes nodes min nodes max ssh access ssh public key frank open distro managed vpc public subnets subnet addc subnet bbbe vpc private subnets subnet bedfd subnet fdccabe And sure enough I got the same Error I experimented with different kube config yaml files adding AWS Credentials to the AWS Connections page but I only seemed to get different errors see the end with details of the error I created a quick DAG to output the info of the identity when the DAG was runningshowconfig BashOperator task id sts show bash command aws sts get caller identity this output the following UTC subprocess py INFO UTC subprocess py INFO UserId ARHELLOROKHELLOXUIXJ AmazonMWAA airflow UTC subprocess py INFO Account AWS ACCOUNT UTC subprocess py INFO Arn arn aws sts AWS ACCOUNT assumed role mwaa eks multi account role AmazonMWAA airflow UTC subprocess py INFO I then updated the Trust Association of the MWAA role so it looked like this Version Statement Effect Allow Principal Service airflow env amazonaws com airflow amazonaws com Action sts AssumeRole Effect Allow Principal AWS arn aws sts AWS ACCOUNT assumed role mwaa eks multi account role AmazonMWAA airflow Action sts AssumeRole and then updated the original kube config yaml with two extra linesapiVersion vclusters cluster certificate authority data LStreadacted server name arn aws eks eu central AWS ACCOUNT cluster mwaa ekscontexts context cluster arn aws eks eu central AWS ACCOUNT cluster mwaa eks user arn aws eks eu central AWS ACCOUNT cluster mwaa eks name awscurrent context awskind Configpreferences users name arn aws eks eu central AWS ACCOUNT cluster mwaa eks user exec apiVersion client authentication ks io vbeta args region eu central eks get token cluster name mwaa eks role arn aws iam AWS ACCOUNT role mwaa eks multi account role iam command awsAnd once I had saved this uploaded the new kube config yaml when I ran the DAG again success UTC taskinstance py INFO Executing lt Task KubernetesPodOperator pod task gt on UTC standard task runner py INFO Started process to run task UTC standard task runner py INFO Running airflow tasks run kubernetes pod example iam authenticator pod task manual T job id raw subdir DAGS FOLDER ks iam py cfg path tmp tmpnytrk error file tmp tmpozbhr UTC standard task runner py INFO Job Subtask pod task UTC logging mixin py INFO Running lt TaskInstance kubernetes pod example iam authenticator pod task manual T running gt on host ip eu central compute internal UTC taskinstance py INFO Exporting the following env vars AIRFLOW CTX DAG OWNER awsAIRFLOW CTX DAG ID kubernetes pod example iam authenticatorAIRFLOW CTX TASK ID pod taskAIRFLOW CTX EXECUTION DATE T AIRFLOW CTX DAG RUN ID manual T UTC kubernetes pod py INFO Creating pod mwaa pod test efadfecacaeecfaedbb with labels dag id kubernetes pod example iam authenticator task id pod task execution date T afd try number UTC pod manager py WARNING Pod not yet started mwaa pod test efadfecacaeecfaedbb UTC pod manager py WARNING Pod not yet started mwaa pod test efadfecacaeecfaedbb UTC pod manager py INFO AWS ACCOUNT UTC pod manager py WARNING Pod mwaa pod test efadfecacaeecfaedbb log read interrupted but container base still running UTC pod manager py INFO UTC pod manager py INFO Pod mwaa pod test efadfecacaeecfaedbb has phase Running UTC kubernetes pod py INFO skipping deleting pod mwaa pod test efadfecacaeecfaedbb UTC taskinstance py INFO Marking task as SUCCESS dag id kubernetes pod example iam authenticator task id pod task execution date T start date T end date T UTC local task job py INFO Task exited with return code UTC local task job py INFO downstream tasks scheduled from follow on schedule checkI hope this helps someone out took me a few hours to get this working Let me know if you found this useful AppendixI thought I would post this here as it might help someone One of the configuration changes I made was to deploy an updated kube config yaml that looked like this apiVersion vclusters cluster certificate authority data LStL readacted server name arn aws eks eu central AWS ACCOUNT cluster mwaa ekscontexts context cluster arn aws eks eu central AWS ACCOUNT cluster mwaa eks user arn aws eks eu central AWS ACCOUNT cluster mwaa eks name awscurrent context awskind Configpreferences users name arn aws eks eu central AWS ACCOUNT cluster mwaa eks user exec apiVersion client authentication ks io vbeta args region eu central token i mwaa eks command aws iam authenticatorHowever when using this configuration I got the following error UTC kubernetes pod py INFO Creating pod mwaa pod test edebaebceed with labels dag id kubernetes pod example iam task id pod task execution date T cdfe try number UTC refresh config py ERROR Errno Permission denied aws iam authenticator UTC kubernetes pod py ERROR Reason ForbiddenHTTP response headers HTTPHeaderDict Audit Id bbcf ab b ade fcbae Cache Control no cache private Content Type application json X Content Type Options nosniff X Kubernetes Pf Flowschema Uid bddf f ed cbff X Kubernetes Pf Prioritylevel Uid dd fa d cbb Date Thu Jan GMT Content Length Hkubernetes client rest ApiException Reason ForbiddenHTTP response headers HTTPHeaderDict Audit Id cc eb baedbaa Cache Control no cache private Content Type application json X Content Type Options nosniff X Kubernetes Pf Flowschema Uid bddf f ed cbff X Kubernetes Pf Prioritylevel Uid dd fa d cbb Date Thu Jan GMT Content Length HTTP response body kind Status apiVersion v metadata status Failure message pods is forbidden User system anonymous cannot list resource pods in API group in the namespace mwaa reason Forbidden details kind pods code During handling of the above exception another exception occurred Traceback most recent call last File usr local airflow local lib python site packages airflow task task runner standard task runner py line in start by fork args func args dag self dag File usr local airflow local lib python site packages airflow cli cli parser py line in command return func args kwargs File usr local airflow local lib python site packages airflow utils cli py line in wrapper return f args kwargs File usr local airflow local lib python site packages airflow cli commands task command py line in task run run task by selected method args dag ti File usr local airflow local lib python site packages airflow cli commands task command py line in run task by selected method run raw task args ti File usr local airflow local lib python site packages airflow cli commands task command py line in run raw task error file args error file File usr local airflow local lib python site packages airflow utils session py line in wrapper return func args session session kwargs File usr local airflow local lib python site packages airflow models taskinstance py line in run raw task self execute task with callbacks context File usr local airflow local lib python site packages airflow models taskinstance py line in execute task with callbacks result self execute task context self task File usr local airflow local lib python site packages airflow models taskinstance py line in execute task result execute callable context context File usr local airflow local lib python site packages airflow providers cncf kubernetes operators kubernetes pod py line in execute remote pod remote pod File usr local airflow local lib python site packages airflow providers cncf kubernetes operators kubernetes pod py line in cleanup raise AirflowException f Pod pod and pod metadata name returned a failure remote pod airflow exceptions AirflowException Pod mwaa pod test edebaebceed returned a failure None UTC local task job py INFO Task exited with return code UTC local task job py INFO downstream tasks scheduled from follow on schedule checkMy lack of knowledge of how Kubernetes authentication and authorisation works let me down here so if anyone knows how to fix this then please let me know |
2023-01-26 15:48:15 |
海外TECH |
DEV Community |
Flaky Tests, and How to Deal with Them |
https://dev.to/codux/flaky-tests-and-how-to-deal-with-them-2id2
|
Flaky Tests and How to Deal with Them IntroHey My name is Yarden Porat and in this article I will explain what flaky tests are their costs their causes and how they harm your work and organization Once we have that figured out I will share our strategy and tools we have developed in house for dealing with test flakiness at Wix and how we avoid their costs What is a flaky test A flaky test is an automated test with a non deterministic result This is a way of saying that a test sometimes passes and sometimes doesn t inconsistently without any code changes How often does it fail Beautifully depicted in this article if a single test has a failure rate of and you have of these tests in your test suite it would have a success rate of But what happens when you have thousands of these tests A success rate It s easy to calculate the significant impact of even a low failure rate on large scale tested applications But…What s the problem Just rerun the tests There are some really bad implications of ignoring flaky tests Let s go over some of the most common ones from least important to most Wasted CI minutes Hours Days Weeks Consider the following scenario You are a developer working in a team There s a new feature you ve been developing for several days and you opened a pull request wanting to merge it into the project Now your company works in a modern development workflow and runs automated tests on your code changes using your CI system All of the product s tests ran and failed on a test entirely unrelated to the changes you introduced Since you are aware of the code changes you have made and you know that this project has issues with non deterministic tests you therefore know the failing test is not your fault So you rerun the test and it passes If you don t know your project has an issue with non deterministic tests you ll probably waste even more time investigating The problem is that this time accumulates The longer the test workflows take the more time is wastedーbut how much time This can be measured assuming you track your CI test results You can easily calculate the CI time wasted due to flakiness by summing up the CI time of a workflow run that had a non deterministic result For example commitworkflow nameosresultdurationfetest part linuxsuccessfetest part linuxfailRun identifier commit workflow name osThat s minutes of CI time wasted Wasted development timeWhen a developer reruns a test they are forced to wait again for the build and test time Precious developer time is being lost Even if we assume that a developer utilizes this wait time for other tasks we still have major drawbacks Loss of immediate feedback long feedback loop Context switchingーwhich eats away at focus and productivity Unfortunately this wasted time is much harder to measure Flaky product behavior or flaky implementation Sometimes a flaky test is only a symptom of a non deterministic implementation The same race condition that can cause test flakiness can do the same in a feature s implementation thus causing flaky product behavior in production Alert fatigueA common phenomenon in flaky test workflow is the loss of trust in the feedback you are getting Consider this scenario You push your new codeWorkflow tests run and fail“Oh it s that annoying flakiness again we should fix it sometime Rerun workflow tests run and fail“D N FLAKINESS Rerun workflow tests run and failRealizing that it was actually my code changes that had failed the testsGo back to step This harms development velocity and the developer s experience In an environment where it s not mandatory for tests to pass to merge a pull request it is not uncommon for changes to merge even though they are breaking some product and tested behavior What s lost Money Developer time CI time Development velocityConfidence in tests regressing to manual testing Product qualityDeveloper experience Causes of test flakinessSo now that we know the price and the pain here are some of the causes of test flakiness Poorly written test codeFor example interacting with DOM elements that are not yet ready or improper use of waitFor functions This is the most common case where testing is done incorrectly Sometimes powerful development machines a k a your local computer hide race conditions in a test which ends up failing on CI machines Poorly written application codeAs mentioned above sometimes the application code itself introduces a flaky behavior These cases are much harder to detect and debug It could be related to communications asynchronous code or many other alternatives Infrastructural causesThere are various environmental causes to blame and they are the immediate culprit for those who write flaky tests Such causes may be Network issues loss of connectivity slow connection etc Hardware issues low performance shared virtual machines which stress existing race conditionsExternal dependencies package manager npm yarn runtime setup i e Node and other dependencies which also suffer from some level of flakiness Test tools that are prone to flakinessIn our experience tests which use a browser are more prone to flakiness One reason is that the browser itself is a complex piece of software with many dependencies and it can be affected by a variety of factors its version operating system and other specific configurations of the machine it is running on Key takeaways up to this pointHere are some points I think you should keep in mind Flaky tests could occur due to many reasons and various causes Some are test related some production code related others from the infrastructure and development environment They have direct and indirect implications on the development processーboth technical and psychological Flaky tests reduce development speed and quality if left untreated How to deal with flaky tests Collect dataIt is much easier to communicate the costs of flakiness to your team or organization if you have data to back you up Analyze it Workflow reruns per day bar graphA bar graph that represents the overall flakiness and displays the total number of times a workflow has been restarted It helps us understand the scale of the flakiness problem and the lack of developer trust in the tests CI At Codux we chose to count any case of workflow rerun but you can also create a subset of this graph that shows reruns that never succeeded which could better depict the lack of trust in your tests CI This is a general index that tells if your data correlates with your general feel of flakiness We don t derive tasks from it We count rerun by identifying the commit branch OS and workflow name We call it an “entity and count its total occurrences minus one Fail rate tableThis is a table that calculates a test s fail rate out of its total runs We collect data from all branches including development branches and present only tests that have failed on branches or more with a minimum number of total runs This table helps us find the current culprits tests A Flaky test that fails over an arbitrary percentage of your choice we chose is skipped documented and assigned to the relevant developer This process occurs times a week This process requires reasoning and shouldn t in our opinion be done automatically ーfor example Some features have a low number of tests so you probably wouldn t want to lose coverage and you might prefer or should add a retry on those tests Some tests are more prone to failure during development such as end to end tests so it might indicate they have a higher fail rate than they actually do Fail by test scatter plot Environmental factors We ve created a plot similar to Spotify s Odeneye This plot helps us realize if there are some environmental or infrastructural problems If you suspect your infrastructure is causing flakiness try creating this dashboard Horizontal lines indicate that a test is flaky Vertical lines indicate an issue external to the test because it shows multiple test failures in the same timeframe Run new tests multiple timesAfter noticing that newly created tests are flaky and require adjustments we have decided to raise the bar for newly created tests and created “check new flaky ーa CLI tool that detects new tests and runs them multiple times It detects new tests by running our test runner mocha programmatically recursively extracting test names on the branch and comparing them to master Checking newly created tests reduced the new flaky tests added to the application and the need to refactor them significantly Some more benefits that we got Faster feedback loop This test workflow runs your new tests immediately thus letting you know if it passes without waiting for their turn within the entire test suiteAnother OS is running your test All our tests are running on Linux while tests features which are considered to be operating system sensitive also run on Windows Using the check new flaky CLI we sometimes get an indication that a test we thought wasn t OS sensitive is actually sensitive or broken for the other operating system Set a bar for when a test isn t flakyAt first it wasn t really clear to a developer when he fixed a flaky test Developers would usually run a test times before it would be labeled as not flaky and get merged to master Once we declared war on test flakiness the bar would be set to consecutive runs There are many ways to run a test multiple times ーwe used parts from the above CLI check new flaky and made it accessible via our GitHub bot Does your test only fail when running on CI CI machines usually have reduced performance compared to your local development machine thus most race conditions only show once tests are running on the CI Helping tests fail on your local machineOne tool that we have found to be helpful is CPU throttling emulation We use Playwright for integration and end to end browser tests It emulates slow CPUs using the Chrome Devtools Protocol experimental feature import type ChromiumBrowserContext from playwright core const client await page context as ChromiumBrowserContext newCDPSession page await client send Emulation setCPUThrottlingRate rate Rate is the slowdown factor is no throttle is x slowdown Find out what s going on with a test on the CIMany testing tools today allow you to take some recordings of your tests Playwright released a tracing feature on version which records the test flow and provides us with screenshots and DOM snapshots Since we had a significant issue with flaky tests we immediately integrated this feature into our testing utils allowing developers to record runs We send CI tracing to a dedicated Slack channel for ease of use This feature is super helpful when you have no clue why the test is failing on CI Tracing helped us catch some unimaginable bugs that we wouldn t have caught otherwise Stop using ElementHandles Start using Playwright LocatorsFollowing the release of Playwright Locators and ElementHandle being discouraged from use we decided to migrate our test kits and test drivers to Locators to enjoy the benefits given to us by this new API actionability check more strictness detailed below and in our React application reduced flakiness From our experience we can say that simply replacing ElementHandles with Locators in a test can resolve flakiness by itself What s wrong with ElementHandles Each ElementHandle refers to an actual specific DOM node React when trying to reconcile changes might replace these referred DOM nodes This is happening due to changes or as a result of components being unmounted and remounted again making the referenced ElementHandle irrelevant Keeping references to specific DOM nodes is not really needed because we usually get those references with selectors ーwhich are agnostic to specific DOM nodes How Locators help us to get the correct DOM nodeLocators keep the selector itself rather than a reference to a specific DOM node Upon action e g click the locator Uses the selector to query the DOM node relevant for that tryVerifies it is actionable attached clickable etc Validates there is no single multiple mismatch Repeats the process until it succeeds The actionability validation is batched along with the action itself as an atomic action For example an atomic action could be check if the button is available visible clickable and only then click it ーmeaning less communication between node and the browser By doing the query and validation alongside the action we prevent possible race conditions that could occur between waitFor gt client re render gt action Some more benefitsIncreased strictness default locator will throw an exception if the selector matched more than one element More readable errors depicts the exact issue of why an action cannot be done instead of a failing assertion or some generic timeout Final wordsBattling flakiness isn t a short term thing It requires developers awareness and care writing tests more carefully keeping in mind possible race conditions and a conscience that tells them it isn t okay to just rerun tests It requires assistive tooling for testing the test itself and monitoring it It requires priority time and guidelines ーthings you should receive from the technical management thus requiring them to be aware of this issue A single developer cannot change the state of flakiness ーa group effort is needed Flakiness is a manageable long term battle Empower yourself with the right tools to not only increase your development velocity but also elevate your overall experience Sources Shopify Engineering The Unreasonable Effectiveness of Test Retries An Android Monorepo Case StudySpotify Engineering Test Flakiness Methods for identifying and dealing with flaky testsGoogle Testing Blog Flaky Tests at Google and How We Mitigate ThemRethinking Productivity in Software Engineering Edited by Caitlin Sadowski Thomas Zimmermann page The Cost of Context SwitchingPlaywright newCDPSession |
2023-01-26 15:45:35 |
海外TECH |
DEV Community |
Create Your Own tRPC Stack! |
https://dev.to/nx/create-your-own-trpc-stack-3lg7
|
Create Your Own tRPC Stack Table of ContentsThe Evolution of Awesome Tec StacksBuilding Our Concrete Example StackCreating a Code Generation ScriptUsing that ScriptDefining a Task ExecutorUsing that ExecutorPutting it All Together The Evolution of Awesome Tech Stacks LAMP the OG Tech StackArguably the first tech stack that was called as such was the LAMP stack which was traced back to a issue of the German computing magazine Computertechnik LAMP here was an acronym that stood for L Linux the operating system A Apache the HTTP server M MySql or sometimes MariaDB the database P PHP Perl Python the programing language There was something magical about this idea of a tech stack This bundle of free to use open sourced and relatively interchangeable software was a viable maybe even preferable alternative to the many paid proprietary and locking in packages that were popular at the time and gave rise to some killer applications like WordPress An interesting essential part of this idea of a stack was the concept of interchangeable pieces note how the P in particular could stand for VERY different programming languages and a close cousin to LAMP was WAMP which exchanged Linux for Windows First Gen JS stacks MEAN MERNAs we move on from the early s to the s the JavaScript ecosystem in particular started growing in popularity spurred by the creation of Node js in which was accompanied by a JS package manager npm With this popularity came the rise of the first all JS stack the MEAN stack which stood for M Mongo a JSON JavaScript Object Notation based DatabaseE Express a Web Framework for Node jsA AngularJS a frontend JS web frameworkN NodeJS a backend Javascript runtime environmentA later evolution of this stack was the MERN stack that exchanged React with AngularJS as the frontend web framework While this first generation of JavaScript stacks made for a recognizable and searchable term for describing a typical setup there was little in the way of standardizing this stack Current Gen JS stacks T tRPC TanstackStepping into the current generation of JavaScript in the s and while we re still early in this generation of JS stacks a clear trend can be seen in the form of a focus on tooling and the developer experience A stand outs from this generation of the JS stack is the t stack which is an opinionated and evolving collection of the following technologies A marked difference we can see from the MEAN MERN stacks of the previous generation is that while MEAN MERN operated mainly as a convenient search term to give needed context to looking up problems the t stack is much more formalized including a website a community of support on discord and Twitter and importantly a CLI tool to create a working starter application This CLI is exciting as it is a way of standardizing and versioning the stack over time If the community identifies a specific tool or enhancement that it can canonically bring into the stack the generative nature of this tool gives developers a working starting point Still they can work from there to bring in their tools to further customize their stack The impact on the developer however is the ultimate goal here as the t tenants of ruthless practicality Developers should be focused on solving their problems Using create t app clearly demonstrates this after answering a short series of questions the developer has an operational full stack application that they can see in action with one simple command to start up the project locally Other popular packages in this generation include the tanstack series of packages and tRPC While not fully fledged stacks the way t is these projects are likely successful mainly due to the attention given to tooling particularly type safety This positions them as obvious building blocks for other stacks to incorporate The Next Step NxWe think that Nx is uniquely positioned to be an essential tool in this current generation of JS stacks Nx is built on a series of core tooling features that benefit most repositories especially monorepos including code generation mechanisms that allow you to quickly scaffold an entire project structure or add features such as Tailwind to an existing projecta way of visualizing how sections of your code are connected via the project graphmechanisms to ensure speed while just running commands via the nx affected command and task cachinga mechanism for defining how commands in your workspace depend on each other via task pipeline configurationa way to easily extend tooling via a plugin mechanismWhile all the above features help make things faster for any project Nx s pluggability is particularly interesting for our discussion about stacks At Nx we maintain many packages that are designed to be used as building blocks for developers to create their own stacks Framework based packages like our React Angular Nest and Node packages offer developers a way of assembling their own stack based on their preferences For instance adding a react application to your repository with react router dom installed and pre configured to match their getting started guide is as simple as running the command npx nx g nrwl react app my app routingThen to complement this frontend application with a backend written with NestJS you run the command npx nx g nrwl nest app api frontendProject my appThis will not only create a backend Nest application for you but also configure your React application to create a proxy for your API requests to this Nest application This otherwise tedious task will often waste developer time Other tooling based packages like our Vite Webpack and Rollup packages offer support for build test and Linting level tools allowing easy migration to the tool that best suits your preferences with the added benefit of allowing for painless transitions from using webpack to vite or vice versa In addition to the official Nx packages comes a registry of community supported plugins that support other frameworks tools and languages that we don t have official support for These community supplied plugins offer more building blocks to create your desired stack And our Nx plugin package provides an API for creating your own building blocks and composing other building blocks into a pre defined stack just like the t stack Building Our Concrete Example StackWith this context in mind let s dive into creating our concrete stack specifically React as our frontend ApplicationTailwind for styling on our frontend appExpress for our backend applicationVite and Vitest for frontend bundling and testingEsbuild for backend buildingtRPC for building our API and full stack type safety across both appsWe can build upon Nx s official plugins for the first five items and write our generators for the tRPC pieces based on their Getting Started documentation The end goal is to have a codified and versioned stack that will allow us to create a full stack application in one command and then be able to serve the entire working stack in a single command Here s a teaser of how this will all look when we re finished And you can see and clone the workspace we ll create here Creating our Plugin Before starting this section create an initial workspace using the command create nx workspace latest nx trpc example preset empty and then install our dependencies by running the commands gt yarn add D nrwl react nrwl vite nrwl node nrwl nx plugin nrwl esbuild gt yarn add trpc client trpc server gt npx nx g nrwl react init gt npx nx g nrwl vite init gt npx nx g nrwl node init gt npx nx g nrwl esbuild initWe ll need the above to install manually but in the sequel to this guide we ll create our own init generator script so that any consumers of our package won t need to run this step manually Next to create our plugin we ll run the command npx nx g nrwl nx plugin plugin plugin minimalThis will use the plugin generator of the nrwl plugin package to create a plugin for our workspace named plugin We re also using the minimal flag here so the plugin is empty initially Once this command is run we ll see the new project in libs pluginThe scaffolding of this project is separated into executors and generators where executors are an Nx mechanism to define a task like building an app or starting a web server for local development simplified to a simple Typescript function and generators are an Nx mechanism for code generation simplified to a simple Typescript function We ll see these more in the following sections starting with generators Create a Full Stack Application Generator Nx s Generator API simplifies any code gen script to a simple function The nrwl devkit package goes on to provide utility functions to make the more burdensome things about code generation scripts more manageable and tolerable When we consider at a high level what our code generation should look like we can separate it into these four steps generate a front end applicationgenerate a corresponding backend applicationgenerate a tRPC server library that is already imported into our backend applicationgenerate a tRPC client library that is already imported by our frontend applicationBecause first party Nx generators from the official Nx packages are functions as well we can create a corresponding function for all four of the points above and then call those Nx generators in sequence to implement our generator Now that we have our roadmap for the generator we also need to consider how we ll want to parameterize our generator The Nx CLI uses a schema based approach to defining these options so that when another developer uses our code generation script they can pass any of these options to the CLI which will be passed as parameters to our generator function we ll write next Given this let s limit our options for now to the following the name of the full stack application This will be required and we ll use this name to inform how we ll name the four projects to generate for this app name web name server name trpc server and name trpc client the port for the backend and the frontend applications to run on These won t be required and we ll default them to and respectively With these in mind we ll create our application generator using the command npx nx g nrwl nx plugin generator app project pluginWhich will use the generator generator of the nrwl nx plugin package to create our new generator named app located at libs plugin src generators app Once the command is run you should see new files located in libs plugin src generators app and metadata for this new app generator in libs plugin generators json The file libs plugin generators json will define all the generators contained in our plugin to Nx but we won t need to touch this file as the generator already took care of any changes required As for the other files created we ll start with libs plugin src generators app schema d ts export interface AppGeneratorSchema name string frontendPort number backendPort number This interface matches the parameterization of the generator we want to support mentioned above We ll also want to adjust the libs plugin src generators app schema json file to match this as well This schema file will inform all Nx tools including the CLI validation the CLI help option and the Nx Console tool what options are available for this generator Notice that the name property is the only required parameter and lines above tell us that it is the first non named option in our command s argument vector or argv npx nx generate nx trpc example plugin app testSo for example the above command would create our new application with the name test and frontendPort and backendPort would use their default values We can add specific values for these options by providing it to our command like so npx nx generate acme dev plugin app test frontendPort Next we can remove the libs plugin src generators app files directory as we won t use that mechanism for this generator The nrwl nx plugin creates this files directory to support templating with Nx generators via the writeFiles function created in the generator ts file The generators we re creating in this article are relatively simple so we ll use string literals when changing a file s contents The implementation of our generator will be written in the libs plugin src generators app generator ts file The mental model here is we will implement these steps in the following function import Tree from nrwl devkit import AppGeneratorSchema from schema export default async function tree Tree options AppGeneratorSchema implementation to go here Our tree parameter represents a virtual file system of the current state of our repo We ll use this Tree API and utility functions from the nrwl devkit package to mutate that tree object until it matches the desired state You can find the entire contents of that file here and you can see our original high level four step approach to the generator export default async function tree Tree options AppGeneratorSchema await createReactApplication tree optionsWithDefaults webAppName await createNodeApplication tree optionsWithDefaults serverName webAppName await createTrpcServerLibrary tree optionsWithDefaults trpcServerName await createTrpcClientLibrary tree optionsWithDefaults trpcClientName That s most of our high level view of what a generator is and how to create it you can skip ahead to using the generator but otherwise let s dive in deeper by walking through the implementation of each of these functions next Adding Default Options and Project NamesAs a preliminary step we ll define the default values for the optional parameters lines below Then we ll create our optionsWithDefaults by spreading the defaultPorts with the options coming in from the command This has the effect of overwriting the defaultPorts if the user provides their own but otherwise the defaults are used We ll also import the names function from the nrwl devkit package so that we can kebab case the name provided by the user For example if the user provided name is helloWorld the fileName of this will be hello world We ll use this to get a name of our four projects in kebab case to use later on in the generator Other cases supported by the names function include pascal caseconsole log names helloWorld className HelloWorldcamel case console log names helloWorld propertyName helloWorldscreaming snake case console log names helloWorld constantName HELLO WORLDuntouched console log names uNtOuChEd name uNtOuChEdWe ll use some of these later on Create Our React AppFor this step we ll create a function called createReactApplication async function createReactApplication tree Tree options AppGeneratorSchema webAppName string implementation will go here Our first step in this function will be to use Nx s first party React app generator We can import it like so import applicationGenerator as reactAppGenerator from nrwl react Notice we re renaming applicationGenerator to reactAppGenerator because we ll be importing other applicationGenerators in future steps When it comes time to call the function we ll call it like so Note that Typescript Intellisense can help us with the required and optional options in lines above The options we ve provided will set up the application with vite and vitest and we ll give it the appropriate port Note that if we ever wanted to adjust our bundler to webpack in the future making that change is as simple as changing the bundler option here Also note that since the reactAppGenerator we imported is an async function we want to make sure we await it Without awaiting we could get a race condition that would give us interesting and undesired results It may be a good idea to test our generator out incrementally For example at this point we can confirm that our React application is generated as expected To do this I recommend using git to commit all changes you ve made so far right before running the generator npx nx g nx trpc example plugin app testYou can check that things look good and then reset to discard all the results so you can continue building the generator git add amp amp git reset hard HEADAnother tool you have for previewing changes from your generator is the dry run option This will list all files that would have been created updated or deleted by the generator without actually running them npx nx g nx trpx example plugin app test dry runThe Nx React plugin includes a generator for adding Tailwind to a React application so we ll import it and call it next import setupTailwindGenerator from nrwl react async function createReactApplication tree Tree options AppGeneratorSchema webAppName string await reactAppGenerator tree name webAppName linter Linter EsLint style css eeTestRunner none unitTestRunner vitest bundler vite devServerPort optionsWithDefaults frontendPort await setupTailwindGenerator tree project webAppName rest of implementation to come here Our next step is to add the boilerplate to import the tRPC client that we ll generate in step to our new app tsx file of our React application import getWorkspaceLayout names Tree from nrwl devkit function createAppTsxBoilerPlate tree Tree name string const className fileName names name const npmScope getWorkspaceLayout tree const appTsxBoilerPlate import create className TrpcClient from npmScope fileName trpc client import useEffect useState from react export function App const welcomeMessage setWelcomeMessage useState useEffect gt create className TrpcClient welcomeMessage query then welcomeMessage gt setWelcomeMessage welcomeMessage return lt h className text xl gt welcomeMessage lt h gt export default App tree write apps fileName web src app app tsx appTsxBoilerPlate Notice that we re anticipating our import statement to match the trpc client library that we ll create in Step and using the client to query for a welcomeMessage that we ll define in our trpc server library in Step Also note that we use the write method of the Tree api here to write a file to our virtual file system Other methods on the Tree api include read exists delete rename isFile children listChanges changePermissions The nrwl devkit also includes a list of utility functions to manipulate our tree more deftly You can find the whole list hereWe re also using the getWorkspaceLayout function of the devkit so that we can match the correct import scope that Nx uses by default for Typescript imports Our last step for now on the React application is to adjust the default port to match the port provided by the user We re also using the updateJson utility function from the nrwl devkit to update our React app s project json file to change the options port of our serve target to the provided port line above With these pieces now created we can finish our createReactApplication function now async function createReactApplication tree Tree options AppGeneratorSchema webAppName string await reactAppGenerator tree name webAppName linter Linter EsLint style css eeTestRunner none unitTestRunner vitest bundler vite devServerPort options frontendPort await setupTailwindGenerator tree project webAppName createAppTsxBoilerPlate tree options name adjustDefaultDevPort tree options Create Our Backend Node AppWe ll take a similar approach to create our Node application starting by importing the nrwl node application generator Notice that we are adding a frontendProject to the options line above This will add a proxy configuration to our React app s development server allowing us to side step CORS complications in our local environment We ll also adjust the contents of the main ts file that is already created after the Promise returned by this nodeAppGenerator resolves function createServerBoilerPlate tree Tree name string backendPort number const fileName names name const npmScope getWorkspaceLayout tree const serverBoilerPlate This is not a production server yet This is only a minimal backend to get started import express from express import as trpcExpress from trpc server adapters express import trpcRouter from npmScope fileName trpc server import environment from environments environment const app express app use api trpcExpress createExpressMiddleware router trpcRouter const port environment port const server app listen port gt console log Listening at http localhost port api server on error console error tree write apps name server src main ts serverBoilerPlate tree write apps name server src environments environment ts export const environment production false port backendPort Note that we re anticipating an import of the trpcRouter that we ll generate in step and we re also using the backendPort from our options to write this port to the environment ts file and thereby configure our backend port Putting these pieces together our resulting function looks like so async function createNodeApplication tree Tree options AppGeneratorSchema serverName string webAppName string await nodeAppGenerator tree name serverName js false linter Linter EsLint unitTestRunner none pascalCaseFiles false skipFormat true skipPackageJson false frontendProject webAppName createServerBoilerPlate tree options name options backendPort Create a Library for Our tRPC ServerWe ll use a similar approach with the nrwl js library generator for this lib import libraryGenerator as jsLibGenerator from nrwl js async function createTrpcServerLibrary tree Tree options AppGeneratorSchema trpcServerName string await jsLibGenerator tree name trpcServerName bundler vite unitTestRunner vitest rest of the implementation to go here After the library is generated we ll add the boilerplate to export our trpc from the index ts file created in this library function createTrpcServerBoilerPlate tree Tree name string const className names name const trpcServerBoilerPlate import initTRPC from trpc server const t initTRPC create export const trpcRouter t router welcomeMessage t procedure query req gt welcomeMessage Welcome to name export type className TrpcRouter typeof trpcRouter tree write libs name trpc server src index ts trpcServerBoilerPlate Note that this creates the welcomeMessage query that we call from app tsx back in step After calling these functions we ll make a few more adjustments to clean up this library remove the libraryName ts file that was generatedremove the libraryName spec ts file that was generatedadd a sourceRoot property to our project json fileThese operations are simple enough that we can inline them in our createTrpcServerLibrary async function createTrpcServerLibrary tree Tree options AppGeneratorSchema trpcServerName string await jsLibGenerator tree name trpcServerName bundler vite unitTestRunner vitest createTrpcServerBoilerPlate tree options name tree delete libs trpcServerName src lib trpcServerName ts tree delete libs trpcServerName src lib trpcServerName spec ts updateJson tree libs trpcServerName project json json gt json sourceRoot libs trpcServerName src Create a Library for Our tRPC ClientWe ll use the same approach and the same nrwl js library generator for this lib as well import libraryGenerator as jsLibGenerator from nrwl js async function createTrpcClientLibrary tree Tree options AppGeneratorSchema trpcClientName string await jsLibGenerator tree name trpcClientName bundler vite unitTestRunner none createTrpcClientBoilerPlate tree options name tree delete libs trpcClientName src lib trpcClientName ts updateJson tree libs trpcClientName project json json gt json sourceRoot libs trpcClientName src function createTrpcClientBoilerPlate tree Tree name string const className fileName names name const npmScope getWorkspaceLayout tree const trpcClientBoilerPlate import className TrpcRouter from npmScope fileName trpc server import createTRPCProxyClient httpBatchLink from trpc client export const create className TrpcClient gt createTRPCProxyClient lt className TrpcRouter gt links httpBatchLink url api as any tree write libs fileName trpc client src index ts trpcClientBoilerPlate The client here is pretty trivial and not expected to change so we ll use none for our unitTestRunner option to avoid adding unit tests for this lib Putting Our Whole Generator TogetherWith all this in place we re good to go To recap here s the entirety of our function now import getWorkspaceLayout names Tree updateJson from nrwl devkit import applicationGenerator as nodeAppGenerator from nrwl node import libraryGenerator as jsLibGenerator from nrwl js import applicationGenerator as reactAppGenerator setupTailwindGenerator from nrwl react import AppGeneratorSchema from schema import Linter from nrwl linter const defaultPorts frontendPort backendPort export default async function tree Tree options AppGeneratorSchema const optionsWithDefaults defaultPorts options const kebobCaseName names optionsWithDefaults name fileName const webAppName kebobCaseName web const serverName kebobCaseName server const trpcServerName kebobCaseName trpc server const trpcClientName kebobCaseName trpc client await createReactApplication tree optionsWithDefaults webAppName await createNodeApplication tree optionsWithDefaults serverName webAppName await createTrpcServerLibrary tree optionsWithDefaults trpcServerName await createTrpcClientLibrary tree optionsWithDefaults trpcClientName omitting the function implementations but they would go below hereWhich reads like a list of exactly what we set out to do at the start The generators in your Local Plugin can serve as the expected scaffolding for our stack codified as well as automated This way if you decide to alter your stack or change this scaffolding you can adjust your generators via a Pull Request That pull request can serve as a discussion place to verify the change and once merged your stack will follow the new standard Use your Generator To use the generator now run the command npx nx generate nx trpc example plugin app testWhere nx trpc example is the name of our workspace plugin is the name of the plugin we created app is the name of the generator we created and test is the name of the full stack app we want to create After creating our test app via the generator we can run the command to start our server npx nx serve test serverAnd in a separate terminal we can run the command npx nx serve test webTo run our react application that communicates with our server This should give us our full stack development environment to respond to our saves as long as these serve commands are running But wouldn t it be great to run this in the same terminal via a single command In the next section we ll create an executor that will allow us to run both of these serves in a single command Create an Executor Next we ll add a way to run both the frontend and backend applications in a development mode in a single command As it turns out Nx gives us a way out of the box to do this via npx nx run many target serve gt NX Running target serve for projects test server test web ー gt nx run test server serve gt nx run test web serve developmentLoading proxy configuration from Users zackderose nx recipes trpc example stack apps test web proxy conf json ➜Local Debugger listening on ws localhost cbd df e cc decdecDebugger listening on ws localhost cbd df e cc decdecFor help see Listening at http localhost api watch build succeeded watching for changes With that in place both our client and server are started with the one command but it s difficult to tell in the terminal which line belongs to which process so we ll address this by creating an executor so that our resulting terminal looks like this That s everything for the high level view of understanding of executors Feel free to skip ahead to how we can use this executor once it s created or other stick around for an in depth explanation of the implementation details Our goal in Nx s task running API is to simplify any task to a single function an executor When we use Nx to run a task like with the command npx nx build my app Nx will determine the executor function attached to my app s build target and call that executor function To create an executor that will serve both the front and backend applications we ll start by running the command npx nx g nrwl nx plugin executor serve fullstack project pluginThis will run the executor generator of the nrwl nx plugin package to create an executor called serve fullstack in our plugin library with all the scaffolding managed for us Not unlike our generator we can adjust the parameterization of the executor here starting with the libs plugin src executors serve full stack schema d ts export interface ServeFullstackExecutorSchema frontendProject string backendProject string This will require us to provide the name of the frontendProject and backendProject in the options of any targets we set up for this executor We ll also add the corresponding libs plugin src executors serve full stack schema json file schema version cli nx title ServeFullstack executor description type object properties frontendProject type string description The name of the frontend project to serve backendProject type string description The name of the backend project to serve required frontendProject backendProject With that setup we ll start in the libs plugin src executors serve fullstack executor ts file While we could take a similar approach as our generators and import the executors from our nrwl packages this is not as feasible for our use case Long running executors a task that is expected to keep running until canceled for instance a serve as opposed to executors that complete at some point like a build return an AsyncInterator from the existing first party Nx Executors currently which are a bit more challenging to work with So instead we ll use Node s child process api to use Nx s CLI to call the serve s of our web app and server Then we ll listen to emissions from these processes stdio and stderr and log them with a good looking prefix In the end it should look like this Starting our ServerWe ll start by running the server first as we ll need our server running for our web server s proxy to be created correctly when we start running it Here s the code to do so The startBackendServer function will return a Promise that never resolves This will ensure that the task will never complete this is another way of achieving a long running task in addition to the AsyncIterators mentioned before Line above creates the child process and lines will ensure that if our parent process ends like if the user pressed CTRL C while it s running the child process will be kill ed as well On lines we ll also listen for the substring build succeeded watching for changes here to start up our frontend serve next Note the second input here the ExecutorContext on line above We won t use this in the generator in this example Still when Nx calls this function to run our executor it will provide all of this potentially helpful context information in the second parameter here which is useful for many other use cases Starting our React AppWe ll use the following function to start up our frontend server async function startFrontendServer frontendProject string return new Promise gt const childProcess exec npx nx serve frontendProject maxBuffer LARGE BUFFER process on exit gt childProcess kill process on SIGTERM gt childProcess kill This should look very similar to the function we wrote to start our backendProject With this function in place we can adjust our startBackendServer function now to call this only the first the backend server starts correctly Notice we added a variable to track whether we ve started the frontend server before on line above and we added a check in line just before calling our startFrontendServer function on line Adding Good Looking Prefixes to Our logsAt this point our executor is functional but if we run it right now the logs will be empty We ll fix this by creating a function that when given a ChildProcess and a prefix will relay anything logged by the process to the parent s stdout Since we want the prefixes to look nice later we ll use chalk that Nx already has as a dependency so it s already installed and add some logic to center the name of the project and make all prefixes take the same amount of space Lines above create a reusable function to prefix every line of any incoming string and send it to the parent process s stdout by calling console log and lines set up hooks to call this function whenever the given ChildProcess writes to stdout or stderr The function to padTargetName on lines above will ensure that our prefix is centered and the same length as any other project name All that s left is to put it all together now Notice lines above determines the targeted prefix width and we adjusted our startBackendServer and our startFrontendServer functions to accept this as a parameter as well and lines and add our prefixTerminalOutput so both the ChildProcesses are prefixed correctly Use your Executor To use our executor we ll start by adding a new target to our apps test web project json file Lines above add a new serve fullstack target to our test web app that we already created with our generator Line tells it to use the executor we just wrote and lines give that executor the required parameters we set up for it All that s left to do now is call this target from the Nx CLI npx nx serve fullstack test web Putting it All Together As a bonus step now that we have our executor set up we can automate this step of adding the serve fullstack target to the right project json file Going back to libs plugin src generators app generator ts and specifically the createReactApplication function we can add another function called addFullStackServeTarget and call it after generating the rest of our react application Starting at line we use nrwl devkit s updateJson function to do just this to the project json of the react app that we ll create in this generator As we can see in the result the whole picture of what we ve created allows us to stamp out any number of full stack applications to add to our monorepo s workspace given simply a name and optionally a frontend or backend port We are then fully set up to execute a full stack serve where we can easily distinguish the logs from our frontend vs backend serve processes as we saw in our original teaser RecapIn this article we looked at the history and evolution of tech stacks and saw how Nx is positioned to be an integral part of creating and maintaining tech stacks in the future While this plugin currently exists only within our current workspace that we built together we ll follow up this blog post with another on how to publish and share your plugin with the broader community including an init generator for installing required packages and a preset generator for creating a new workspace from scratch Learn moreNx DocsNx GitHubNrwl Community SlackNrwl Youtube ChannelNeed help with Angular React Monorepos Lerna or Nx Talk to us If you liked this click the ️and make sure to follow Zack and Nx on Twitter for more |
2023-01-26 15:38:55 |
海外TECH |
DEV Community |
Movie App With Next.js 13, TailwindCSS & TypeScript 😍 |
https://dev.to/said_mounaim/movie-app-with-nextjs-13-tailwindcss-typescript-386m
|
Movie App With Next js TailwindCSS amp TypeScript Movie AppA movie app that allows users to view and search for movies and see details of each movie This app is still in progress and is built using Next js TailwindCSS TypeScript and TheMovieDB API Getting StartedClone the repository git clone Install dependencies npm installStart the development server npm run dev Built WithNext jsTailwindCSSTypeScriptTheMovieDB API ContributionAll kind of contributions are welcome please feel free to submit pull requests Github RepoGithub Profile |
2023-01-26 15:01:58 |
Apple |
AppleInsider - Frontpage News |
Daily Deals Jan. 26: $310 off 14-inch MacBook Pro, Apple Studio Display $1,299, 24-inch iMac $1,099 & more |
https://appleinsider.com/articles/23/01/26/daily-deals-jan-26-310-off-14-inch-macbook-pro-apple-studio-display-1299-24-inch-imac-1099-more?utm_medium=rss
|
Daily Deals Jan off inch MacBook Pro Apple Studio Display inch iMac amp moreSome of the most valuable deals we discovered today include Apple s Mac mini M for up to off Kindle devices and a inch iMac for Save on a MacBook ProThe AppleInsider Team reviews the web for excellent deals at online retailers to develop a top notch list of discounts on the best tech gadgets including deals on Apple products TVs accessories and other items We post the best deals in our Daily Deals post to help you save money Read more |
2023-01-26 15:02:30 |
Apple |
AppleInsider - Frontpage News |
How to open links in Apple Maps instead of Google Maps |
https://appleinsider.com/inside/apple-maps/tips/how-to-open-links-in-apple-maps-instead-of-google-maps?utm_medium=rss
|
How to open links in Apple Maps instead of Google MapsSo you prefer Apple Maps but everybody else uses Google Maps But there are ways to open Google Maps links in Apple Maps ーhere s how Apple Park as shown in Apple Maps If you own an iPhone you ve almost certainly considered whether you should use Apple Maps or Google Maps on your travels Read more |
2023-01-26 15:35:51 |
海外TECH |
CodeProject Latest Articles |
Design a Windows Explorer Extension with SharpShell |
https://www.codeproject.com/Articles/5353060/Design-a-Windows-Explorer-Extension-with-SharpShel
|
explorer |
2023-01-26 15:10:00 |
金融 |
RSS FILE - 日本証券業協会 |
株券等貸借取引状況(週間) |
https://www.jsda.or.jp/shiryoshitsu/toukei/kabu-taiw/index.html
|
貸借 |
2023-01-26 15:30:00 |
金融 |
金融庁ホームページ |
農林中央金庫及び商工組合中央金庫に関する「レバレッジ比率規制に係る告示の一部改正(案)」に対するパブリック・コメントの結果等について公表しました。 |
https://www.fsa.go.jp/news/r4/ginkou/20230126.html
|
商工組合中央金庫 |
2023-01-26 17:00:00 |
金融 |
金融庁ホームページ |
金融審議会「事業性に着目した融資実務を支える制度のあり方等に関するワーキング・グループ」(第7回)を開催します。 |
https://www.fsa.go.jp/news/r4/singi/20230125-2.html
|
金融審議会 |
2023-01-26 17:00:00 |
金融 |
金融庁ホームページ |
審判期日の予定を更新しました。 |
https://www.fsa.go.jp/policy/kachoukin/06.html
|
期日 |
2023-01-26 16:00:00 |
金融 |
金融庁ホームページ |
名古屋電機工業(株)社員からの情報受領者による内部者取引に対する課徴金納付命令の決定について公表しました。 |
https://www.fsa.go.jp/news/r4/shouken/20230125-1.html
|
内部者取引 |
2023-01-26 16:00:00 |
金融 |
金融庁ホームページ |
(株)YE DIGITAL株式外1銘柄に係る相場操縦に対する 課徴金納付命令の決定について公表しました。 |
https://www.fsa.go.jp/news/r4/shouken/20230125-2.html
|
yedigital |
2023-01-26 16:00:00 |
ニュース |
BBC News - Home |
Transgender rapist Isla Bryson to be moved from women's prison |
https://www.bbc.co.uk/news/uk-scotland-64413242?at_medium=RSS&at_campaign=KARANGA
|
cornton |
2023-01-26 15:25:57 |
ニュース |
BBC News - Home |
Ukraine hit by Russian missiles day after West's offer of tanks |
https://www.bbc.co.uk/news/world-europe-64411259?at_medium=RSS&at_campaign=KARANGA
|
people |
2023-01-26 15:26:09 |
ニュース |
BBC News - Home |
German man arrested for allegedly passing intelligence to Russia |
https://www.bbc.co.uk/news/world-europe-64415814?at_medium=RSS&at_campaign=KARANGA
|
russia |
2023-01-26 15:22:05 |
ニュース |
BBC News - Home |
Ben Youngs says rugby union has 'risks' and 'rewards' following tackle height changes |
https://www.bbc.co.uk/sport/rugby-union/64414430?at_medium=RSS&at_campaign=KARANGA
|
Ben Youngs says rugby union has x risks x and x rewards x following tackle height changesEngland s most capped male player Ben Youngs insists the rewards of rugby union outweigh the risks as the debate over the controversial tackle law rages on |
2023-01-26 15:23:29 |
ニュース |
BBC News - Home |
Vinicius Jr: Effigy prompts condemnation of 'repugnant' behaviour towards Real Madrid winger |
https://www.bbc.co.uk/sport/football/64414425?at_medium=RSS&at_campaign=KARANGA
|
Vinicius Jr Effigy prompts condemnation of x repugnant x behaviour towards Real Madrid wingerLa Liga says it strongly condemns acts of hatred and intimidation against Vinicius Jr after an effigy of the Real Madrid winger is hung from a bridge |
2023-01-26 15:12:28 |
コメント
コメントを投稿